jinja2中继承的嵌套多块看不到二​​级作用域变量

时间:2019-01-29 21:07:13

标签: inheritance scope nested jinja2

在较高的层次上,我想创建一个基本模板(baseex.j2),该模板使用嵌套循环在list dict列表的dict列表的嵌套dict上循环。我的希望是baseex.j2将抽象出循环和其他Jinja特定内容,并留下子模板来描述这些嵌套块的内容。

Q1:这种方法是否可能? 问题2:如果不是,是否有类似的东西(多继承,带有块的循环递归) 问题3:如果可能,我在做什么错了?

基本模板baseex.j2:

{%- for a in as %}
  {%- set a_loop = loop %}
  {%- block a scoped %}
    {{a.name}} {{ a_loop.index }}
    {%- for r in a.rs %}
      {%- set r_loop = loop %}
      {%- block r scoped %}
        {{r.name}} {{ r_loop.index }}
        {%- for f in r.fs %}
          {%- set f_loop = loop %}
          {%- block f scoped %}
            {{f.name}} {{ f_loop.index }}
          {%- endblock %}
        {%- endfor %}
      {%- endblock %}
    {%- endfor %}
  {%- endblock %}
{%- endfor %}

数据示例ex.json:

{"as":[{"name":"a_a","rs":[{"name":"b_r","fs":[{"name":"c_f"},{"name":"d_f"}]}]},{"name":"e_a","rs":[{"name":"f_r","fs":[{"name":"g_f"},{"name":"h_f"}]}]}]}

CLI接受json输入和多个jinja模板j2dirjson:

#!/usr/bin/env python

# Inputs: Jinja2 Template Dir, Target Template and JSON file
# Output: rendered result to stdout

from jinja2 import Environment, FileSystemLoader, Template
import json5 as json
import sys

j2_env = Environment(loader=FileSystemLoader(sys.argv[1]))


template = j2_env.get_template(sys.argv[2])

with open(sys.argv[3]) as fd:
    data = json.load(fd)

print(template.render(data))%                                                              

因此,如果我仅通过baseex.j2模板运行ex.json:

j2dirjson . baseex.j2 ex.json

我得到了预期的输出:

    a_a 1
        b_r 1
            c_f 1
            d_f 2
    e_a 2
        f_r 1
            g_f 1
            h_f 2

现在,我创建一个子模板be.md.j2:

{%- extends "baseex.j2" %}
{%- block a %}
  {{a_loop.index}}
  {%- block r %}
    {{r_loop.index}}
    {%- block f %}
    {%- endblock %}
  {%- endblock %}
{%- endblock %}

并运行它:

j2dirjson . be.md.j2 ex.json

但是得到这个结果:

Traceback (most recent call last):
  File "j2dirjson", line 20, in <module>
    print(template.render(data))
  File "/usr/lib/python2.7/dist-packages/jinja2/environment.py", line 1008, in render
    return self.environment.handle_exception(exc_info, True)
  File "/usr/lib/python2.7/dist-packages/jinja2/environment.py", line 780, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "./be.md.j2", line 1, in top-level template code
    {%- extends "baseex.j2" %}
  File "./baseex.j2", line 3, in top-level template code
    {%- block a scoped %}
  File "./be.md.j2", line 4, in block "a"
    {%- block r %}
  File "./be.md.j2", line 5, in block "r"
    {{r_loop.index}}
  File "/usr/lib/python2.7/dist-packages/jinja2/environment.py", line 430, in getattr
    return getattr(obj, attribute)
jinja2.exceptions.UndefinedError: 'r_loop' is undefined

我看过文档: http://jinja.pocoo.org/docs/2.10/templates/#block-nesting-and-scope

并尝试了类似的操作,例如将scoped添加到子块(与文档无关(无关紧要))。

0 个答案:

没有答案