Синтаксис шаблонів Jinja
Last updated
Last updated
- это просто текстовый файл. может генерировать любой текстовый формат (HTML, XML, CSV, LaTeX и т. д.). Шаблон Jinja не обязательно должен иметь конкретное расширение: вполне подойдет .html
, .xml
или любое другое расширение.
Шаблон содержит переменные и/или выражения, которые заменяются значениями при визуализации шаблона, также применяются теги, управляющие логикой шаблона. Синтаксис шаблона во многом вдохновлен Django и Python.
Ниже приведен минимальный шаблон, который иллюстрирует некоторые основы использования конфигурации Jinja по умолчанию.
В примере показаны параметры конфигурации по умолчанию. Разработчик приложения может изменить конфигурацию синтаксиса с {% foo %}
на <% foo %>
или что-то подобное.
Есть несколько видов разделителей. Разделители Jinja по умолчанию настроены следующим образом:
Как сказано выше, файл с любым расширением может быть загружен в качестве шаблона. Добавление расширения .jinja
, такого как user.html.jinja
, может облегчить работу некоторых IDE или плагинов, используемых редактором кода. Автоэкранирование HTML, может применяться на основе расширения файла, в этом случае необходимо будет учитывать дополнительный суффикс.
Еще одна хорошая эвристика для идентификации шаблонов заключается в том, что по умолчанию они находятся в папке templates
, независимо от расширения. Это общий макет для проектов.
Переменные могут иметь атрибуты или элементы, к которым можно получить доступ в шаблонах. Какие атрибуты имеют переменные, сильно зависит от приложения, предоставляющего эту переменную.
В шаблонах можно использовать точку (.
) для доступа к атрибутам переменной в дополнение к стандартному синтаксису индексирования ([]
) в Python __getitem__()
.
Следующие строки делают одно и то же:
Если переменная или атрибут не существует в контексте шаблона, то на выходе получите неопределенное значение Undefined
. То, что можно сделать с таким значением, зависит от конфигурации приложения: поведение по умолчанию значения Undefined
это возврат пустой строки ''
.
Реализация
Для удобства выражение foo.bar
в Jinja выполняет следующие действия на слое Python:
проверяет наличие атрибута getattr(foo, 'bar')
,
если нет, то проверяет наличие элемента foo.__getitem__('bar')
,
если его нет, то возвращает неопределенный объект Undefined
.
Выражение foo['bar']
работает в основном так же с небольшой разницей в последовательности:
проверяет наличие элемента foo.__getitem__('бар')
,
если его нет, проверяет наличие атрибута getattr(foo, 'bar')
,
если его нет, то возвращает неопределенный объект Undefined
.
В шаблонах Jinja2 можно использовать любой из методов, определенных для типа переменной. Значение, возвращаемое при вызове метода, используется как значение выражения. Вот пример, в котором используются методы, определенные для строк, где page.title
- это строка:
Это работает для методов с пользовательскими типами. Например, если для переменной foo
типа Foo
определен метод bar
, то можно сделать следующее:
Операторы Python работают также, как и ожидается. Например, оператор Python %
реализует для строк стиль printf
:
Хотя в этом случае лучше использовать метод строки str.format()
, который немного надуман в контексте рендеринга шаблона:
Переменные можно изменять с помощью фильтров. Фильтры отделяются от переменной вертикальной чертой (|
) и могут иметь необязательные аргументы в круглых скобках. Можно объединить несколько фильтров. Выходные данные одного фильтра применяются к следующему.
Например, выражение шаблона {{ name|striptags|title }}
удалит все HTML-теги из переменной name
и напечатает все слова с заглавной буквы. Вызов последовательности фильтров будет следующим title(striptags(name))
.
Фильтры, которые принимают аргументы, заключают аргументы в круглые скобки, как и при вызове функции Python. Например: выражение шаблона {{ listx|join(',') }}
объединит список строк listx
в одну строку, а в качестве разделителя будет использовать запятую ', '
. Вызов фильтра будет следующим join(listx, ',')
.
В шаблонах jinja2 дополнительно можно использовать разделы фильтров, которые позволяют применять фильтры к блоку данных шаблона.
Тесты тоже могут принимать аргументы. Если тест принимает только один аргумент, то скобки можно опустить. Например, следующие два выражения делают одно и то же:
Чтобы закомментировать часть строки в шаблоне, используйте синтаксис комментария, который по умолчанию установлен на {# ... #}
. Это полезно, чтобы закомментировать части шаблона для отладки или добавить информацию для других разработчиков шаблона, а также для себя:
В конфигурации по умолчанию:
Один завершающий символ новой строки удаляется, если он присутствует.
Другие пробелы (пробелы, табуляции, новые строки и т. д.) возвращаются без изменений.
Если включены как trim_blocks
, так и lstrip_blocks
, то можно помещать теги блоков в их собственные строки, и вся строка блока будет удалена при рендеринге, сохраняя пробелы в содержимом. Например, без установленных аргументов trim_blocks
и lstrip_blocks
этот шаблон:
Отображается с пустыми строками внутри div:
Но при включенных аргументах trim_blocks
и lstrip_blocks
строки блока шаблона удаляются, а остальные пробелы сохраняются:
Можно вручную отключить поведение lstrip_blocks
, поставив знак плюса (+
) в начале блока:
Примечание: НЕ НАДО добавлять пробелы между тегом и знаком минус.
Иногда желательно (даже необходимо) чтобы модуль Jinja игнорировал части, которые в противном случае обрабатывались как переменные или блоки. Например, если с синтаксисом по умолчанию необходимо использовать парные фигурные скобки {{
как необработанную строку в шаблоне, то самый простой способ это сделать - использовать выражение переменной {{ '{{' }}
Для больших разделов имеет смысл пометить блок как необработанный. Например, чтобы включить пример синтаксиса Jinja в шаблон, можно использовать фрагмент:
Примечание. Знак минус в конце тега {% raw -%}
очищает все пробелы и символы новой строки, предшествующие первому символу необработанных данных.
Префикс строки для оператора может появляться в любом месте строки, если ему не предшествует текст. Для удобства чтения операторы, которые начинают блок (например, for
, if
, elif
и т. д.), могут заканчиваться двоеточием:
Примечание. Строчные операторы могут охватывать несколько строк, если есть открытые круглые скобки ()
, фигурные скобки {}
или квадратные скобки []
:
Начиная с Jinja 2.2, также доступны построчные комментарии. Например, если окружение Environment
настроено с аргументом line_comment_prefix='##'
, то все от символов ##
до конца строки игнорируется (за исключением знака новой строки):
Оператор шаблона with
позволяет создать новую внутреннюю область видимости. Переменные, установленные в этой области, не видны за пределами области.
В двух словах:
Так как обычно переменные устанавливаются в начале области видимости, это можно сделать с помощью оператора шаблона with
. Следующие два примера эквивалентны:
В версиях Jinja до 2.9 обращение одной переменной к другой имело непредвиденные последствия. В частности, одна переменная может ссылаться на другую, определенную в той же теге шаблона with
, что вызвало проблемы и с тех пор было улучшено. В частности, в более новых версиях Jinja следующий код всегда ссылается на переменную a
извне блока with
:
В более ранних версиях Jinja атрибут b
будет относиться к результатам первого атрибута. Если код зависит от этого поведения, то можно переписать его, чтобы использовать тег шаблона set
:
Примечание. В более старых версиях Jinja до 2.9 требовалось включить эту функцию с помощью расширения. Теперь эта функциональность включена по умолчанию.
При желании можно активировать и деактивировать автоматическое экранирование HTML прямо из шаблонов.
После блока autoescape
поведение возвращается к тому, что было раньше.
Примечание. В более старых версиях Jinja до 2.9 требовалось включить эту функцию с помощью расширения. Теперь эта функциональность включена по умолчанию.
{% ... %}
используется операторами шаблонов, такими как , , , и т.д.
{{ ... }}
используется для написания для печати на выходе шаблона.
{# ... #}
используется для , не включенных в выходные данные шаблона
# ... ##
используется для .
;
;
;
;
;
;
;
;
;
;
;
.
Переменные шаблона определяются , переданным в шаблон при помощи метода .
Важно понимать, что внешние двойные фигурные скобки {{ ... }}
не являются частью переменной, а являются частью оператора шаблона для вывода переменной/выражения на печать. Если нужно обратится к переменным внутри тегов {% ... %}, например при использовании в , то не заключайте переменные в фигурные скобки.
Это важно, если объект имеет элемент и атрибут с одинаковым именем. Кроме того, ищет только атрибуты.
Дополнительно смотрите с их описанием и примерами использования в шаблонах, а также как .
Помимо фильтров, доступны так называемые тесты. Тесты можно использовать для проверки переменной на соответствие общему выражению. Чтобы проверить , необходимо добавить после переменной is
плюс имя теста. Например, чтобы узнать, определена ли переменная, можно написать что то на подобное name is defined
, которое затем вернет истину или ложь в зависимости от того, определено ли name
в текущем контексте шаблона.
Дополнительно смотрите с их описанием и примерами использования в шаблонах.
Если настроить модуль Jinja при , то первая новая строка после тега шаблона {% .. %}
удаляется автоматически. Также в Environment
может быть установлен аргумент lstrip_blocks
для удаления табуляции и пробелов от начала строки до начала блока {% .. %}
(ничего не будет удалено, если перед началом блока есть другие символы).
Также можно удалить пробелы в шаблонах вручную. Если добавить знак минус (-
) в начало или конец блока (например, ), комментария или выражения переменной, то пробелы до или после этого блока будут удалены:
Эта разметка шаблона напечатает все элементы без пробелов между ними. Если бы переменная seq
была чисел от 1 до 9, то на выходе было бы напечатано 123456789
.
Если включены , то они автоматически удаляют начальные пробелы до начала строки.
По умолчанию Jinja также удаляет завершающие символы новой строки. Чтобы сохранить одиночные завершающие символы новой строки, настройте с аргументом keep_trailing_newline=True
.
Если в приложении разрешены строчные операторы, то можно пометить строку как оператор. Например, если при инициализации , для аргумента line_statement_prefix
задано значение '#'
, то следующие два примера эквивалентны: