Использование макросов в шаблонах Jinja2.
Макросы шаблонов Jinja2 сопоставимы с функциями в обычных языках программирования. В шаблонах Jinja2 макросы определяются тегами
{% macro ... %}{% endmacro %}
. Они полезны для того, чтобы поместить часто используемые идиомы в многоразовые функции, чтобы не повторяться.
Смотрим небольшой пример макроса, который отображает элемент формы:
{% macro input(name, value='', type='text', size=20) -%}
<input type="{{ type }}" name="{{ name }}" value="{{
value|e }}" size="{{ size }}">
{%- endmacro %}
Затем макрос шаблона можно вызвать как функцию в пространстве имен:
<p>{{ input('username') }}</p>
<p>{{ input('password', type='password') }}</p>
Если макрос был определен в другом шаблоне, то его необходимо сначала
импортировать при помощи выражения
{% import 'forms.html' as forms %}
.
Внутри макросов пользователь имеет доступ к трем специальным переменным:
varargs
: если макросу передается больше позиционных аргументов, чем определяет макрос, то они попадают в специальную переменную varargs
в виде списка значений.kwargs
: работает как varargs
, но для ключевых аргументов. Все неиспользованные ключевые аргументы хранятся в этой специальной переменной.caller
: если макрос был вызван из тега {% call ... %}
, то вызываемый объект хранится в этой переменной как вызываемый макрос.
Макросы также раскрывают некоторые из своих внутренних деталей. Для объекта макроса доступны следующие атрибуты:
name
: имя макроса. Например {{ input.name }}
распечатает input
.arguments
: кортеж имен аргументов, которые принимает макрос.defaults
: кортеж значений по умолчанию.catch_kwargs
: вернет True
, если макрос принимает дополнительные ключевые аргументы (т. е. специальная переменная kwargs
не пуста).catch_varargs
: вернет True
, если макрос принимает дополнительные позиционные аргументы (т. е. специальная переменная varargs
не пуста).caller
: вернет True
, если макрос обращается к специальной переменной вызывающего объекта и может быть вызван из тега {% call ... %}
.
Если имя макроса начинается с подчеркивания, то он не может быть
импортирован.
Блок вызова {% call ... %}
в шаблоне Jinja2.
В некоторых случаях может быть полезно передать макрос другому макросу. Для этого можно использовать специальный блок {% call ... %}
. В следующем примере показан макрос, который использует преимущества функции вызова и как его можно использовать:
{% macro render_dialog(title, class='dialog') -%}
<div class="{{ class }}">
<h2>{{ title }}</h2>
<div class="contents">
{{ caller() }}
</div>
</div>
{%- endmacro %}
{% call render_dialog('Hello World') %}
Это простой диалог, отображаемый с помощью
макроса и блока вызовов.
{% endcall %}
Также можно передавать аргументы обратно в блок вызова {% call ... %}
. Такое поведение делает его полезным в качестве замены циклов. Вообще, блок вызова {% call ... %}
работает точно так же, как макрос без имени.
Вот пример того, как блок вызова можно использовать с аргументами:
{% macro dump_users(users) -%}
<ul>
{%- for user in users %}
<li><p>{{ user.username|e }}</p>{{ caller(user) }}</li>
{%- endfor %}
</ul>
{%- endmacro %}
{% call(user) dump_users(list_of_user) %}
<dl>
<dl>Realname</dl>
<dd>{{ user.realname|e }}</dd>
<dl>Description</dl>
<dd>{{ user.description }}</dd>
</dl>
{% endcall %}