Spec-Zone.ru › Twig 3

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

Также, 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, когда опция strict_variables установлена в 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 %}

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

Функции

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

Например, функция 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" }}

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

Первая строка после тега шаблона удаляется автоматически (как в 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> #}

Расширения

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/3.x/templates.html

Spec-Zone.ru

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