унаследованный вложенный мультиблок в jinja2 не может видеть переменные второго уровня - PullRequest
0 голосов
/ 30 января 2019

На высоком уровне я хотел создать базовый шаблон (baseex.j2), который использует вложенные циклы для циклического обхода вложенного dict списка dict списка dict списка.Я надеялся, что baseex.j2 абстрагирует циклы и другой специфический для jinja контент и оставит дочерний шаблон для описания содержимого этих вложенных блоков.

В1: Возможен ли такой подход?Q2: если нет, есть ли что-то подобное (мульти-наследование, рекурсивное для циклов с блоками) Q3: если возможно, что я делаю не так?

базовый шаблон 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))%                                                              

Так что, если я запускаю ex.json только через шаблон baseex.j2:

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 кдочерние блоки (что из документа не имеет значения (и не имеет значения)).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...