Spec-Zone.ru › Twig 2

Twig для разработчиков шаблонов

Этот документ описывает синтаксис и семантику движка шаблонов и будет наиболее полезен в качестве справочника для тех, кто создаёт шаблоны Twig.

Обзор

Шаблон — это обычный текстовый файл. Он может генерировать любой текстовый формат (HTML, XML, CSV, LaTeX и т.д.). У него нет специфического расширения, .html или .xml подойдут.

Шаблон содержит переменные или выражения, которые заменяются значениями при оценке шаблона, и теги, которые управляют логикой шаблона.

Ниже приведён минимальный шаблон, иллюстрирующий некоторые основы. Более подробные сведения будут рассмотрены позднее:

<!DOCTYPE html>
<html>
    <head>
        <title>My Webpage</title>
    </head>
    <body>
        <ul id="navigation">
        {% for item in navigation %}
            <li><a href="{{ item.href }}">{{ item.caption }}</a></li>
        {% endfor %}
        </ul>

        <h1>My Webpage</h1>
        {{ a_variable }}
    </body>
</html>

Существует два вида разделителей: {% ... %} и {{ ... }}. Первый используется для выполнения операторов, таких как циклы for, второй — для вывода результата выражения.

Интеграция с IDE

Многие IDE поддерживают подсветку синтаксиса и автодополнение для Twig:

  • Textmate через пакет Twig bundle
  • Vim через плагин синтаксиса Jinja или плагин vim-twig
  • Netbeans через плагин Twig (до версии 7.1, встроенный начиная с 7.2)
  • PhpStorm (встроенный начиная с версии 2.1)
  • Eclipse через плагин Twig
  • Sublime Text через пакет Twig bundle
  • GtkSourceView через определение языка Twig Twig (используется в gedit и других проектах)
  • Coda и SubEthaEdit через режим синтаксиса Twig Twig
  • Coda 2 через другой режим синтаксиса Twig Twig
  • Komodo и Komodo Edit через режим подсветки/проверки синтаксиса Twig
  • Notepad++ через Notepad++ Twig Highlighter
  • Emacs через web-mode.el
  • Atom через PHP-twig for atom
  • Visual Studio Code через пакет Twig pack

Также, TwigFiddle — это онлайн-сервис, позволяющий выполнять шаблоны Twig из браузера; он поддерживает все версии Twig.

Переменные

Приложение передаёт переменные в шаблоны для обработки в шаблоне. Переменные также могут иметь атрибуты или элементы, к которым можно получить доступ. Визуальное представление переменной сильно зависит от приложения, которое её предоставляет.

Используйте точку (.) для доступа к атрибутам переменной (методы или свойства объекта PHP, или элементы массива PHP):

{{ foo.bar }}

Примечание

Важно знать, что фигурные скобки не являются частью переменной, а частью оператора вывода. При доступе к переменным внутри тегов фигурные скобки не ставьте.

Реализация

Для удобства foo.bar выполняет следующие действия на уровне PHP:

  • проверяет, является ли foo массивом, и bar — допустимым элементом;
  • если нет, и если foo — объект, проверяет, является ли bar допустимым свойством;
  • если нет, и если foo — объект, проверяет, является ли bar допустимым методом (даже если bar — конструктор - используйте __construct());
  • если нет, и если foo — объект, проверяет, является ли getBar допустимым методом;
  • если нет, и если foo — объект, проверяет, является ли isBar допустимым методом;
  • если нет, и если foo — объект, проверяет, является ли hasBar допустимым методом;
  • если нет, возвращает значение null.

Twig также поддерживает специфический синтаксис для доступа к элементам в массивах PHP, foo['bar'].

  • проверяет, является ли foo массивом, и bar — допустимым элементом;
  • если нет, возвращает значение null.

Если переменная или атрибут не существует, вы получите значение null при включенном варианте false; в противном случае, если strict_variables включён, Twig выведет ошибку (см. параметры окружения).

Примечание

Если нужно получить доступ к динамическому атрибуту переменной, используйте функцию attribute вместо этого.

Функция attribute также полезна, когда атрибут содержит специальные символы (например, -, который интерпретируется как оператор минус):

{# equivalent to the non-working foo.data-foo #}
{{ attribute(foo, 'data-foo') }}

Глобальные переменные

Следующие переменные всегда доступны в шаблонах:

  • _self: ссылается на текущее имя шаблона;
  • _context: ссылается на текущий контекст;
  • _charset: ссылается на текущую кодировку.

Установка переменных

Можно присваивать значения переменным внутри блоков кода. Присвоение выполняется с помощью тега set:

{% set foo = 'foo' %}
{% set foo = [1, 2] %}
{% set foo = {'foo': 'bar'} %}

Фильтры

Переменные могут быть изменены с помощью фильтров. Фильтры отделяются от переменной символом «|» (|). Можно использовать несколько фильтров последовательно. Результат одного фильтра передаётся на вход следующему.

В следующем примере удаляются все HTML-теги из name и выполняется приведение к верхнему регистру:

{{ name|striptags|title }}

Фильтры, принимающие аргументы, имеют круглые скобки вокруг аргументов. В этом примере элементы списка соединяются запятыми:

{{ list|join(', ') }}

Чтобы применить фильтр к части кода, оберните её тегом apply:

{% apply upper %}
    This text becomes uppercase
{% endapply %}

Дополнительные сведения о встроенных фильтрах см. на странице фильтров.

Примечание

Тег apply был добавлен в Twig 2.9; используйте тег filter для предыдущих версий.

Функции

Для генерации содержимого можно вызывать функции. Функции вызываются по их имени, за которым следуют круглые скобки (()), и могут иметь аргументы.

Например, функция range возвращает список, содержащий арифметическую прогрессию целых чисел:

{% for i in range(0, 3) %}
{{ i }},
{% endfor %}

Дополнительные сведения о встроенных функциях см. на странице функций.

Именованные аргументы

{% for i in range(low=1, high=10, step=2) %}
{{ i }},
{% endfor %}

Использование именованных аргументов делает шаблоны более явными в отношении смысла передаваемых аргументов:

{{ data|convert_encoding('UTF-8', 'iso-2022-jp') }}

{# versus #}

{{ data|convert_encoding(from='iso-2022-jp', to='UTF-8') }}

Именованные аргументы также позволяют пропустить некоторые аргументы, для которых вы не хотите изменять значение по умолчанию:

{# the first argument is the date format, which defaults to the global date format if null is passed #}
{{ "now"|date(null, "Europe/Paris") }}

{# or skip the format value by using a named argument for the time zone #}
{{ "now"|date(timezone="Europe/Paris") }}

Можно также использовать позиционные и именованные аргументы в одном вызове, при этом позиционные аргументы должны всегда предшествовать именованным:

{{ "now"|date('d/m/Y H:i', timezone="Europe/Paris") }}

Подсказка

На каждой странице документации функций и фильтров есть раздел, где перечислены все поддерживаемые имена аргументов.

Структура управления

Структура управления относится ко всем элементам, которые контролируют поток программы — условные операторы (т.е. if/elseif/else), циклы for, а также блоки. Структуры управления появляются внутри блоков {% ... %}.

Например, чтобы отобразить список пользователей, предоставленных в переменной под названием users, используйте тег for:

<h1>Members</h1>
<ul>
    {% for user in users %}
        <li>{{ user.username|e }}</li>
    {% endfor %}
</ul>

Тег if можно использовать для проверки выражения:

{% if users|length > 0 %}
    <ul>
        {% for user in users %}
            <li>{{ user.username|e }}</li>
        {% endfor %}
    </ul>
{% endif %}

Дополнительные сведения о встроенных тегах см. на странице тегов.

Комментарии

Чтобы прокомментировать часть строки в шаблоне, используйте синтаксис комментариев {# ... #}. Это полезно для отладки или добавления информации для других разработчиков шаблонов или для себя:

{# note: disabled template because we no longer use this
    {% for user in users %}
        ...
    {% endfor %}
#}

Включение других шаблонов

Функция include полезна для включения шаблона и возврата отрендеренного содержимого этого шаблона в текущий:

{{ include('sidebar.html') }}

По умолчанию включённые шаблоны имеют доступ к тому же контексту, что и шаблон, который их включает. Это означает, что любая переменная, определённая в основном шаблоне, также будет доступна во включённом шаблоне:

{% for box in boxes %}
{{ include('render_box.html') }}
{% endfor %}

Включённый шаблон render_box.html может получить доступ к переменной box.

Имя шаблона зависит от загрузчика шаблонов. Например, \Twig\Loader\FilesystemLoader позволяет получить доступ к другим шаблонам, задавая имя файла. Вы можете получить доступ к шаблонам в подкаталогах, используя слеш:

{{ include('sections/articles/sidebar.html') }}

Это поведение зависит от приложения, использующего Twig.

Наследование шаблонов

Наиболее мощной частью Twig является наследование шаблонов. Наследование шаблонов позволяет создать базовый шаблон-«каркас», содержащий все общие элементы вашего сайта и определяющий блоки, которые дочерние шаблоны могут переопределить.

Концепцию легче понять, начав с примера.

Определим базовый шаблон, base.html, который определяет HTML-шаблон документа, который может использоваться для страницы с двумя колонками:

<!DOCTYPE html>
<html>
    <head>
        {% block head %}
            <link rel="stylesheet" href="style.css"/>
            <title>{% block title %}{% endblock %} - My Webpage</title>
        {% endblock %}
    </head>
    <body>
        <div id="content">{% block content %}{% endblock %}</div>
        <div id="footer">
            {% block footer %}
                &copy; Copyright 2011 by <a href="http://domain.invalid/">you</a>.
            {% endblock %}
        </div>
    </body>
</html>

В этом примере теги block определяют четыре блока, которые дочерние шаблоны могут заполнить. Все, что делает тег block, — это сообщает движку шаблонов, что дочерний шаблон может переопределить эти части шаблона.

Дочерний шаблон может выглядеть так:

{% extends "base.html" %}

{% block title %}Index{% endblock %}
{% block head %}
    {{ parent() }}
    <style type="text/css">
        .important { color: #336699; }
    </style>
{% endblock %}
{% block content %}
    <h1>Index</h1>
    <p class="important">
        Welcome to my awesome homepage.
    </p>
{% endblock %}

Ключевым здесь является тег extends. Он сообщает движку шаблонов, что этот шаблон «расширяет» другой шаблон. При оценке шаблона система шаблонов сначала находит родительский шаблон. Тег extends должен быть первым тегом в шаблоне.

Обратите внимание, что поскольку дочерний шаблон не определяет блок footer, вместо этого используется значение из родительского шаблона.

Возможно рендеринг содержимого родительского блока с помощью функции parent. Это возвращает результаты родительского блока:

{% block sidebar %}
    <h3>Table Of Contents</h3>
    ...
    {{ parent() }}
{% endblock %}

Подсказка

Страница документации для тега extends описывает более продвинутые функции, такие как вложенность блоков, область видимости, динамическое наследование и условное наследование.

Примечание

Twig также поддерживает множественное наследование через «горизонтальное повторное использование» с помощью тега use.

Обработка HTML-экранирования

При генерации HTML из шаблонов всегда есть риск, что переменная будет содержать символы, влияющие на результирующий HTML. Есть два подхода: ручное экранирование каждой переменной или автоматическое экранирование всего по умолчанию.

Twig поддерживает оба подхода, автоматическое экранирование включено по умолчанию.

Стратегия автоматического экранирования может быть настроена через опцию autoescape и по умолчанию равна html.

Работа с ручным экранированием

Если ручное экранирование включено, вам необходимо экранировать переменные при необходимости. Что экранировать? Любую переменную, которая поступает из ненадежного источника.

Экранирование выполняется с помощью фильтра escape или e:

{{ user.username|e }}

По умолчанию фильтр escape использует стратегию html, но в зависимости от контекста экранирования, вы можете явно использовать другую стратегию:

{{ user.username|e('js') }}
{{ user.username|e('css') }}
{{ user.username|e('url') }}
{{ user.username|e('html_attr') }}

Работа с автоматическим экранированием

Независимо от того, включено ли автоматическое экранирование или нет, вы можете пометить часть шаблона для экранирования или не экранирования с помощью тега autoescape:

{% autoescape %}
    Everything will be automatically escaped in this block (using the HTML strategy)
{% endautoescape %}

По умолчанию автоматическое экранирование использует стратегию экранирования html. Если вы выводите переменные в других контекстах, вам нужно явно экранировать их с помощью соответствующей стратегии экранирования:

{% autoescape 'js' %}
    Everything will be automatically escaped in this block (using the JS strategy)
{% endautoescape %}

Экранирование

Иногда желательно или даже необходимо, чтобы Twig игнорировал части, которые он в противном случае обрабатывал как переменные или блоки. Например, если используется стандартный синтаксис, и вы хотите использовать {{ как строку без обработки в шаблоне, а не начинать переменную, вам нужно использовать трюк.

Самый простой способ — вывести разделитель переменных ({{) с помощью выражения переменной:

{{ '{{' }}

Для больших разделов имеет смысл пометить блок verbatim.

Макросы

Макросы сопоставимы с функциями в обычных языках программирования. Они полезны для повторного использования фрагментов HTML, чтобы не повторять себя. Они описаны в документации к тегу macro.

Выражения

Twig допускает выражения повсюду.

Примечание

Порядок приоритета операторов следующий, с операторами с наименьшим приоритетом в начале: ?: (тернарный оператор), b-and, b-xor, b-or, or, and, ==, !=, <=>, <, >, >=, <=, in, matches, starts with, ends with, .., +, -, ~, *, /, //, %, is (тесты), **, ??, | (фильтры), [], и .:

{% set greeting = 'Hello ' %}
{% set name = 'Fabien' %}

{{ greeting ~ name|lower }}{# Hello fabien #}

{# use parenthesis to change precedence #}
{{ (greeting ~ name)|lower }}{# hello fabien #}

Литералы

Самая простая форма выражений — это литералы. Литералы представляют типы PHP, такие как строки, числа и массивы. Существуют следующие литералы:

  • "Hello World": Всё между двумя двойными или одинарными кавычками — это строка. Они полезны всякий раз, когда вам нужна строка в шаблоне (например, в качестве аргументов для вызовов функций, фильтров или просто для расширения или включения шаблона). Строка может содержать разделитель, если она предваряется обратной косой чертой (\) — как в 'It\'s good'. Если строка содержит обратную косую черту (например, 'c:\Program Files'), экранируйте её, удваивая (например, 'c:\\Program Files').

  • 42 / 42.23: Целые и числа с плавающей точкой создаются путём записи числа. Если присутствует точка, число является числом с плавающей точкой, в противном случае целым числом.

  • ["foo", "bar"]: Массивы определяются последовательностью выражений, разделённых запятыми (,) и заключённых в квадратные скобки ([]).

  • {"foo": "bar"}: Словари определяются списком ключей и значений, разделённых запятыми (,) и заключёнными в фигурные скобки ({}):

    {# keys as string #}
    { 'foo': 'foo', 'bar': 'bar' }
    
    {# keys as names (equivalent to the previous hash) #}
    { foo: 'foo', bar: 'bar' }
    
    {# keys as integer #}
    { 2: 'foo', 4: 'bar' }
    
    {# keys can be omitted if it is the same as the variable name #}
    { foo }
    {# is equivalent to the following #}
    { 'foo': foo }
    
    {# keys as expressions (the expression must be enclosed into parentheses) #}
    {% set foo = 'foo' %}
    { (foo): 'foo', (1 + 1): 'bar', (foo ~ 'b'): 'baz' }
    
  • true / false: true представляет истинное значение, false — ложное значение.

  • null: null представляет собой значение без указания. Это значение, возвращаемое, когда переменная не существует. none является псевдонимом для null.

Массивы и словари могут быть вложены:

{% set foo = [1, {"foo": "bar"}] %}

Подсказка

Использование строк в двойных или одинарных кавычках не влияет на производительность, но интерполяция строк поддерживается только в строках в двойных кавычках.

Математические операции

Twig позволяет выполнять математические операции в шаблонах; поддерживаются следующие операторы:

  • +: Складывает два числа (операнды преобразуются к числам). {{ 1 + 1 }} это 2.
  • -: Вычитает второе число из первого. {{ 3 - 2 }} это 1.
  • /: Делит два числа. Возвращаемое значение будет числом с плавающей точкой. {{ 1 / 2 }} это {{ 0.5 }}.
  • %: Вычисляет остаток от деления целых чисел. {{ 11 % 7 }} это 4.
  • //: Делит два числа и возвращает результат усечения целого числа. {{ 20 // 7 }} это 2, {{ -20  // 7 }} это -3 (это всего лишь синтаксический сахар для фильтра round).
  • *: Умножает левое операнд на правое. {{ 2 * 2 }} вернёт 4.
  • **: Возводит левое операнд в степень правого операнда. {{ 2 ** 3 }} вернёт 8.

Логические операции

Вы можете объединить несколько выражений с помощью следующих операторов:

  • and: Возвращает true, если левое и правое операнды оба истинны.
  • or: Возвращает true, если левое или правое операнд истинно.
  • not: Отрицает утверждение.
  • (expr): Группирует выражение.

Примечание

Twig также поддерживает побитовые операторы (b-and, b-xor, и b-or).

Примечание

Операторы чувствительны к регистру.

Сравнения

В любом выражении поддерживаются следующие операторы сравнения: ==, !=, <, >, >=, и <=.

Вы также можете проверить, является ли строка starts with или ends with другой строкой:

{% if 'Fabien' starts with 'F' %}
{% endif %}

{% if 'Fabien' ends with 'n' %}
{% endif %}

Примечание

Для сложных строковых сравнений оператор matches позволяет использовать регулярные выражения:

{% if phone matches '/^[\\d\\.]+$/' %}
{% endif %}

Оператор включения

Оператор in выполняет проверку включения. Он возвращает true если левый операнд содержится в правом:

{# returns true #}

{{ 1 in [1, 2, 3] }}

{{ 'cd' in 'abcde' }}

Подсказка

Вы можете использовать этот фильтр для выполнения проверки включения для строк, массивов или объектов, реализующих интерфейс Traversable.

Чтобы выполнить отрицательную проверку, используйте оператор not in:

{% if 1 not in [1, 2, 3] %}

{# is equivalent to #}
{% if not (1 in [1, 2, 3]) %}

Оператор проверки

Оператор is выполняет проверки. Проверки могут быть использованы для проверки переменной по отношению к общему выражению. Правый операнд — это имя проверки:

{# find out if a variable is odd #}

{{ name is odd }}

Проверки также могут принимать аргументы:

{% if post.status is constant('Post::PUBLISHED') %}

Проверки могут быть инвертированы с помощью оператора is not:

{% if post.status is not constant('Post::PUBLISHED') %}

{# is equivalent to #}
{% if not (post.status is constant('Post::PUBLISHED')) %}

Перейдите на страницу тестов, чтобы узнать больше о встроенных проверках.

Другие операторы

Следующие операторы не подходят ни под одну из других категорий:

  • |: Применяет фильтр.

  • ..: Создаёт последовательность на основе операнда перед и после оператора (это синтаксический сахар для функции range):

    {{ 1..5 }}
    
    {# equivalent to #}
    {{ range(1, 5) }}
    

    Обратите внимание, что вам необходимо использовать скобки при объединении его с оператором фильтра из-за правил приоритета операторов:

    (1..5)|join(', ')
    
  • ~: Преобразует все операнды в строки и конкатенирует их. {{ "Hello " ~ name ~ "!" }} вернёт (при условии, что name равно 'John') Hello John!.

  • ., []: Получает атрибут переменной.

  • ?:: Условный оператор:

    {{ foo ? 'yes' : 'no' }}
    {{ foo ?: 'no' }} is the same as {{ foo ? foo : 'no' }}
    {{ foo ? 'yes' }} is the same as {{ foo ? 'yes' : '' }}
    
  • ??: Оператор слияния с null:

    {# returns the value of foo if it is defined and not null, 'no' otherwise #}
    {{ foo ?? 'no' }}
    

Вставка строк

Вставка строк (#{expression}) позволяет любому допустимому выражению появляться внутри строки с двойными кавычками. Результат вычисления этого выражения вставляется в строку:

{{ "foo #{bar} baz" }}
{{ "foo #{1 + 2} baz" }}

Управление пробелами

Добавлен в версии 2.8: Управление пробелами на уровне тегов было добавлено в Twig 2.8.

Первая новая строка после тега шаблона автоматически удаляется (как в PHP). Пробелы не изменяются движком шаблонов, поэтому каждый пробел (пробелы, табуляции, новые строки и т. д.) возвращается без изменений.

Вы также можете управлять пробелами на уровне тега. Используя модификаторы управления пробелами для ваших тегов, вы можете обрезать начальные и конечные пробелы.

Twig поддерживает два модификатора:

  • Обрезка пробелов с помощью модификатора -: Удаляет все пробелы (включая новые строки);
  • Обрезка пробелов в строке с помощью модификатора ~: Удаляет все пробелы (исключая новые строки). Использование этого модификатора справа отключает стандартное удаление первой новой строки, унаследованной от PHP.

Модификаторы могут быть использованы с любой стороны тегов, как в {%- или -%}, и они потребляют все пробелы для этой стороны тега. Можно использовать модификаторы с одной стороны тега или с обеих сторон:

{% set value = 'no spaces' %}
{#- No leading/trailing whitespace -#}
{%- if true -%}
    {{- value -}}
{%- endif -%}
{# output 'no spaces' #}

<li>
    {{ value }}    </li>
{# outputs '<li>\n    no spaces    </li>' #}

<li>
    {{- value }}    </li>
{# outputs '<li>no spaces    </li>' #}

<li>
    {{~ value }}    </li>
{# outputs '<li>\nno spaces    </li>' #}

Подсказка

В дополнение к модификаторам пробелов, Twig также имеет фильтр spaceless, который удаляет пробелы между тегами HTML:

{% apply spaceless %}
    <div>
        <strong>foo bar</strong>
    </div>
{% endapply %}

{# output will be <div><strong>foo bar</strong></div> #}

Тег apply был представлен в Twig 2.9; используйте тег filter для предыдущих версий.

Расширения

Twig можно расширять. Если вы хотите создать свои собственные расширения, прочитайте главу Создание расширения.

« Установка | Twig для разработчиков »

© 2009–2018 by the Twig Team
Licensed under the three clause BSD license.
The Twig logo is © 2010–2020 Symfony
https://twig.symfony.com/doc/2.x/templates.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API