Сообщить об ошибке.

Что такое макросы шаблонов jinja2 в Python

Использование макросов в шаблонах 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 %}