#python #django #flask #jinja2
#python #jinja2
Вопрос:
У меня возникают трудности с пониманием поведения контекста при включении файлов в блоки Jinja2. Смотрите этот минимальный пример:
base.jinja2
{% set foo="bar" %}
{% block content %}
{% include 'include.jinja2' %}
{% endblock content %}
включить.jinja2
{{ foo }}
Рендеринг base.jinja2 выдает ошибку foo' is undefined
.
Когда я перемещаю объявление foo
в content
блок, код отображается правильно. То же самое происходит, когда я перемещаю include
инструкцию за пределы content
блока, когда я удаляю content
блок вокруг include
инструкции или когда я заменяю include
инструкцию содержимым файла.
Почему это? Как я могу использовать глобальную переменную foo во включаемом файле внутри блока содержимого?
Ответ №1:
Посмотрите на ссылку, раздел Block Nesting and Scope
:
Блоки могут быть вложенными для более сложных макетов. Однако блоки по умолчанию не могут обращаться к переменным из внешних областей: Причина этого в том, что если блок заменить дочерним шаблоном, появится переменная, которая не была определена в блоке или передана в контекст.
В соответствии с документом и начиная с Jinja 2.2 вы можете изменить это поведение с помощью scoped
.
{% set foo="bar" %}
{% block content scoped %}
{% include 'include.jinja2' %}
{% endblock content %}
Я согласен, что это как-то странно по сравнению с тем, к чему мы привыкли. Но это предполагаемая функция.
Вообще говоря, include передается только контекст. Начиная с версии 2.1, передается производный контекст, который является исходным контекстом все локальные переменные, использованные до инструкции include. Это также означает, что если вы просто используете переменную из внешней области видимости, Jinja2 теперь будет отслеживать ее как локальную и передавать в производный контекст.
Комментарии:
1. Спасибо, это действительно работает. Но почему это работает без,
scoped
когда я не использую включаемый файл и ссылкуfoo
непосредственно в моемcontent
блоке?2. Вообще говоря, include передается только контекст. Начиная с Jinja 2.1, передается производный контекст, который является исходным контекстом все локальные переменные, использованные до инструкции include. Это также означает, что если вы просто используете переменную из внешней области видимости, Jinja2 теперь будет отслеживать ее как локальную и передавать в производный контекст.