Twig

Дополнительные возможности, идущие в комплекте с библиотекой

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

Переменные из Битрикс

  • — экземпляр класса \CMain, который хранится в глобальной переменной
  • — экземпляр класса \CUser, который хранится в глобальной переменной
  • — экземпляр класса \Bitrix\Main\Application, если библиотека работает в битриксе с d7
  • — массив $arResult, сформированный в компоненте. См. примечания по настройке
  • — массив arParams, содержащий параметры компонента
  • — экземпляр класса \CBitrixComponentTemplate для данного шаблона
  • — экземпляр класса \CBitrixComponent для текущего компонента. Следует учитывать, что это не тот класс, который определен в компоненте, а именно \CBitrixComponent
  • — путь до директории текущего шаблона относительно DOCUMENT_ROOT
  • — путь до директории шаблона родительского компонента, если используется комплексный компонент. Эта переменная не учитывает родство шаблонов при использовании, например, функции в twig
  • — массив языкозависимых переменных текущего шаблона. Будет удалено в версии 1.1

Функции из Битрикс

  • — аналог . Данная функция только подключает компонент, но не возвращает результат работы компонента. Если вызывать подключение компонента с помощью объекта , то twig пытается вывести возвращаемое этим методом значение, что приводит часто к появлению артефактов в шаблонах.
  • — синоним для функции или метода , если проект работает с d7
  • и — переменные для генерации подписи с ID сессии в формах, синонимы одноименных функций в битриксе
  • , и — синонимы функций , и

Переменные из PHP

К сожалению, в Битрикс иногда сложно обойтись без использования суперглобальных переменных напрямую в шаблонах, поэтому все суперглобальные переменные из php пробрасываются в каждый шаблон и доступны по именам _SERVER, _GET, _POST, _REQUEST, _SESSION, _COOKIE, _FILES, _ENV и _GLOBALS

Дополнительные функции

С версии 0.5 в библиотеке появились дополнительные удобные функции для работы с шаблонами. На данный момент функция только одна, но их перечень постоянно будет пополняться.

Функция помогает в выводе множественного числа для русских слов. К примеру, вам нужно вывести строку «21 билет». Для этого нужно воспользоваться функцией с такими параметрами в twig:

 {% set ticketsCount = 21 %}
 {{ russianPluralForm(ticketsCount, ) }}

Порядок словоформ запомнить достаточно просто: 0 билетов, 1 билет, 2 билета. Для большинства слов такой порядок будет работать корректно.

Template Inheritance¶

The most powerful part of Twig is template inheritance. Template inheritance
allows you to build a base “skeleton” template that contains all the common
elements of your site and defines blocks that child templates can
override.

It’s easier to understand the concept by starting with an example.

Let’s define a base template, , which defines an HTML skeleton
document that might be used for a two-column page:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
html>
    head>
        {% block head %}
            link rel="stylesheet" href="style.css" />
            title>{% block title %}{% endblock %} - My Webpagetitle>
        {% endblock %}
    head>
    body>
        div id="content">{% block content %}{% endblock %}div>
        div id="footer">
            {% block footer %}
                 Copyright 2011 by a href="http://domain.invalid/">youa>.
            {% endblock %}
        div>
    body>
html>

In this example, the block tags define four blocks that
child templates can fill in. All the tag does is to tell the
template engine that a child template may override those portions of the
template.

A child template might look like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
{% extends "base.html" %}

{% block title %}Index{% endblock %}
{% block head %}
{{ parent() }}

        .important { color: #336699; }

{% endblock %}
{% block content %}
    

Welcome to my awesome homepage.

{% endblock %}

The extends tag is the key here. It tells the template
engine that this template “extends” another template. When the template system
evaluates this template, first it locates the parent. The extends tag should
be the first tag in the template.

Note that since the child template doesn’t define the block, the
value from the parent template is used instead.

It’s possible to render the contents of the parent block by using the
parent function. This gives back the results of the
parent block:

1
2
3
4
5
{% block sidebar %}
    


{{ parent() }}
{% endblock %}

Tip

The documentation page for the extends tag describes
more advanced features like block nesting, scope, dynamic inheritance, and
conditional inheritance.

Краткий обзор

Шаблон — это просто текстовой файл. Вы можете генерировать любой текстовый
формат (HTML, XML, CSV, LaTeX, и тп.). Шаблон может иметь любое расширение,
обычно это или .

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

Рассмотрим небольшой пример шаблона, в котором показаны некоторые основы
создания шаблонов:

html>
    head>
        title>Мой сайтtitle>
    head>
    body>
        ul id="navigation">
        {% for item in navigation %}
            li>a href="{{ item.href }}">{{ item.caption }}a>li>
        {% endfor %}
        ul>

        h1>Моя статьяh1>
        {{ text }}
    body>
html>

Есть два вида разделителей и . Первый используется
для выполнения выражений, например, циклов, второй — для вывода результата
выражения в шаблоне.

Usage

twigc can render Twig templates supplied via either standard input or a file
path.

Passing input data

Input data can be passed to the template using a simple key=value syntax with
:

Of course, only basic string values can be provided this way. For more complex
data, you can use the JSON option :

JSON data can also be provided by file path or on standard input:

(twigc determines whether the argument to is a dictionary string or a
file name based on whether the first character is a ; if you have a file name
that looks like that, use the absolute path or put in front of it — for
example, .)

(If you don’t have in , you’ll get an error.)

Lastly, there’s a option in case you want to pass input as a URL query
string:

All of the aforementioned input options can be given multiple times and in any
combination, but the values associated with each input type override other
values with the same name using the following order of precedence (from lowest
to highest): environment, query, JSON, pair. In other words:

Configuring auto-escaping

The following auto-escape methods are available:

  • (aka , , , &c.) —
    No escaping is performed; the input is rendered as-is. This is the default for
    templates taken from standard input and for files with unrecognised
    extensions.

  • (aka , , , &c.) —
    Ampersand-escaping as suitable for inclusion in an HTML body. This is the most
    common escaping method used for rendering Web pages with Twig, and the default
    method used by the filter.


  • Hex-escaping as suitable for inclusion in a CSS value or identifier.


  • Ampersand-escaping as suitable for inclusion in an HTML attribute value. This
    is similar to the method, but more characters are escaped.


  • Hex-escaping as suitable for inclusion in a JavaScript string or identifier.


  • Serialisation according to JSON rules. Strings are quoted and escaped,
    integers are left bare, &c. JSON escaping can often be used to produce strings
    for config files and even languages like C (though incompatibilities do exist
    — be careful).


  • Double-quoting and meta-character escaping according to shell rules. This
    method uses double-quoted strings rather than the single-quote method used by
    e.g. because it is more compatible with software that
    supports only a sub-set of the shell’s string syntax (such as ‘dotenv’
    libraries).


  • Percent-escaping as suitable for inclusion in a URL path segment or query
    parameter.

Enabling strict mode

By default, references in the template to undefined variables are silently
ignored, but you can make Twig throw an exception with the option:

Use of this option is recommended for reliability in scripting scenarios.

Specifying search directories

If a template file name was provided, the file’s parent directory is
automatically added as an include search path; if standard input was used, no
search path is set at all by default. In either case, one or more additional
search paths can be explicitly supplied on the command line:

Custom template functions

provides these functions to your Twig templates:

  • — returns the URL for a given route. e.g.: /hello/world
  • — returns true is the provided route name and parameters are valid for the current path.
  • — returns the current path, with or without the query string.
  • — returns the object from the incoming object
  • — returns the base path.

You can use to generate complete URLs to any Slim application named route and use to determine if you need to mark a link as active as shown in this example Twig template:

{% extends "layout.html" %}

{% block body %}
h1>User Listh1>
ul>
    li>a href="{{ url_for('profile', { 'name': 'josh' }) }}" {% if is_current_url('profile', { 'name': 'josh' }) %}class="active"{% endif %}>Josha>li>
    li>a href="{{ url_for('profile', { 'name': 'andrew' }) }}">Andrewa>li>
ul>
{% endblock %}

Подключение фильтра «truncate»

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

В нашем случае применить фильтры стоит к создаваемым постам, т.к. их длина может быть достаточно большой.
Выставим ограничение, к примеру, до 100 символов. Но для этой цели стандартные фильтры уже не подходят,
в помощь нам придут расширения для twig.

Установка:

  • — подключаем библиотеку .
    Как видно, Symfony Flex уже не используется.
  • — регистрируем расширение «text extension» из вышеуказаной библиотеки в сервисах.
    Для этого переходим в папку config, открываем services.yaml и добавляем туда следующий код:

    Что должно получиться:

  • — применим фильтр к шаблону , изменив ,
    на ,
    соответственно.
    Для проверки работоспособности просто изменим массив $posts в контроллере
    PostController увеличив длину до 100+ символов.
    Проверяем:

Список шаблонизаторов для сравнения

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

Blade

Этот шаблонизатор используется в Laravel — PHP-фреймворке, начавшем свою жизнь в 2011 г и ставшим одним из популярных PHP-фреймворков. По слухам, причиной скорости Blade является небольшой список регулярных выражений для замены. 

Laravel Github:

Подписчики Звёздочки Форки
4 642 49 438 15 233

Mustache

Mustache доступен для практически неограниченного количества языков, в том числе и PHP. Также он содержит минимум логики: замена, цикл foreach, проверка на null. 

Github:

Подписчики Звёздочки Форки
424 12 804 2 258

Smarty

Smarty появился в начала нулевых, до сих пор развивается и конкурирует с более молодыми проектами.

Github:

Подписчики Звёздочки Форки
197 1 457 473

Twig

Данный шаблонизатор обрёл свою популярность благодаря Фабьену Потенцеруб, внедрившему его в систему представлений фреймворка Symfony. Тем не менее, Twig может быть внедрён практически в любой проект, то есть независимо от фреймворка. 

Github:

Подписчики Звёздочки Форки
257 4 797 1 020

Volt

Volt используется в фреймворке Phalcon (фреймворк, написанный на C и распространяемый как PHP-расширение). Из недостатков можно отметить лишь то, что Volt можно использовать только в Phalcon, то есть нет возможности использовать в проекте на другом фреймворке. 

Phalcon Github:

Подписчики Звёздочки Форки
752 9 460 1 734

Drupal специфичные фильтры

Drupal специфичные фильтры объявлены в TwigExtension::getFilters:

Фильтр t

Фильтр t обрабатывает строку с помощью drupal функции t() и возвращает перевод строки:

В строке можно использовать «заменители» для вставки переменных, значение которых нужно передать в аргумент фильтра в виде ассоциативного массива (подробнее в документации FormattableMarkup::placeholderFormat):

Фильтр placeholder

Фильтр placeholder используется внутри тега trans. Перед выводом переменная экранируется и оборачивается тегом em с классом placeholder. Переменная в строке перевода помечается %:

Фильтр safe_join

Фильтр аналогичен Twig фильтру , за тем лишь исключением, что все элементы массива перед объединением в строку экранируются:

Фильтр without

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

В Drupal 7 тот же самый пример выглядел бы так:

Фильтр clean_class

Фильтр clean_class подготавливает строку для использования ее в качестве валидного имени класса (использует Html::getClass):

Фильтр clean_id

Фильтр clean_id подготавливает строку для использования ее в качестве валидного html атрибута id (использует Html::getId):

Фильтр render

Фильтр render применим к переменным, содержащим рендерные массивы и преобразует массив в уже отрендеренный вывод. Тем не менее применять его в шаблонах к рендерным массивам не нужно, так как все переменные при выводе в шаблоне будут отрендерены.

Фильтр format_date

Фильтр format_date форматирует дату. Первым аргументом принимает формат, который может быть одним из предустановленных: ‘short’, ‘medium’, ‘long’, ‘html_datetime’, ‘html_date’, ‘html_time’, ‘html_yearless_date’, ‘html_week’, ‘html_month’, ‘html_year’ либо же ‘custom’, который позволяет передать во второй аргумент нужный php date формат. Третьим аргументом можно передать часовой пояс, четвертым — код языка для перевода (по умолчанию NULL):

Официальная документация по Twig фильтрам http://twig.sensiolabs.org/doc/filters/index.html

Quick Start

TwigView will look for its templates with the extension .

Layout

Replace by this

html>
head>
    {{ Html.charset()|raw }}

    title>
        {{ __('myTwigExample') }}
        {{ _view.fetch('title')|raw }}
    title>

    {{ Html.meta('icon')|raw }}

    {{ Html.css('default.app.css')|raw }}
    {{ Html.script('app')|raw }}

    {{ _view.fetch('meta')|raw }}
    {{ _view.fetch('css')|raw }}
    {{ _view.fetch('script')|raw }}
head>
body>
    header>
        {{ _view.fetch('header')|raw }}
    header>

    {{ Flash.render()|raw }}

    section>

        h1>{{ _view.fetch('title')|raw }}h1>

        {{ _view.fetch('content')|raw }}
    section>

    footer>
        {{ _view.fetch('footer')|raw }}
    footer>
body>
html>

Template View

Create a template, for example like this

{{ _view.assign('title', __("I'm title")) }}

{{ _view.start('header') }}
    p>I'm headerp>
{{ _view.end() }}

{{ _view.start('footer') }}
    p>I'm footerp>
{{ _view.end() }}

p>I'm contentp>

Шаблонизатор Twig

В мире Symfony принято использовать шаблонизатор
Twig.
Если ранее вы с такими штуками не сталкивались, то возможно хорошо, что twig будет у вас первым.
Вещь удобная и лаконичная, конечно же со своими особенностями и синтаксисом,
привыкнуть к которым не составит никаких проблем.

Давайте подключим его с помощью .
После подключения рецепта в структуре фреймворка появилась папка templates, а в ней шаблон
, который будет общим для всех страниц нашего проекта.


Открываем
и видим несколько конструкций вида .
Таким образом размечаются блоки, которые в дальнейшем вы сможете переопределять
благодаря наследованию. Именно переопределять!
Создавать новые блоки в дочернем шаблоне запрещено.

Давайте перенесем общие части сайта — шапку и подвал из архива
в базовый шаблон, а также подключим стили и скрипты. Ну и начнем с последнего. Располагаться «расходники» будут в папке public нашего проекта.
Просто скопируйте css, js, img из архива в данный каталог.

Теперь верстка. Всего будет 5 страниц (шапка и футер одинаковы для всех):

  • — список новостей;
  • — создание новости;
  • — список пользователей;
  • — регистрация;
  • — логин.

Сейчас нам нужно оставить только общие части шаблона, удалив все лишнее
(попробуйте сначала сделать все самостоятельно).
На текущий момент структура должна иметь следующий вид:

Теперь разместим блоки Twig

Нас интересуют и
.
Обратите внимание на title, в нем указано «Welcome!».
Данный текст является «заглушкой» и будет отображен, если в дочерних блоках мы не переопределим заголовок.. Стили и скрипты подключим с помощью ,
разумеется предварительно их установив при помощи
.
Далее просто начните вводить имя файла и начнет работать автокомплит плагинов, которые мы ранее установили.

Стили и скрипты подключим с помощью ,
разумеется предварительно их установив при помощи
.
Далее просто начните вводить имя файла и начнет работать автокомплит плагинов, которые мы ранее установили.

Отлично, сделано! Но сейчас нам нечего выводить, есть только шапка и футер.
Давайте создадим шаблон для конкретного поста. Для этого создаем папку post в директории templates,
а в post создаем ,
обязательно унаследовав его от базового шаблона с помощью
.

Сейчас мы имеем только один статичный пост, который при любых обстоятельствах выведет нам одно и то же.
Давайте это исправим. Нужно создать конструкцию, в которой посты будут выводиться динамически, каждый
со своим текстом и заголовком. Поможет нам в этом цикл и конструкция
;

Давайте повторим. Мы создали базовый шаблон ,
в нем шапка и футер.
В мы подключаем его с помощью директивы extends,
далее переопределяем блок title для конкретной страницы и блок body.
Делаем это с помощью одноименных с базовым шаблоном конструкций

и . Напомню, что создавая блоки отличные
от родителя — схватите ошибку.

Синтаксические конструкции:

  • {{ переменная }} – в двойных фигурных скобках выводится значение переменной.
    Обращение к объектам производится через точку, без знака ‘$’.
    К элементам массива обращаемся стандартно через квадратные скобки .
    Если значение представляет из себя строку с дефисом, нужно прибегать к конструкции
    .

  • {% условие %} – вывод условий, циклов, а так же подключение блоков.
    Из циклов в twig есть только for, и используется он по аналогии js,
    т.е. пишете .
    Если требуется ключ – .

  • {# комментарий #} – блок комментариев.

Последним шагом осталось протестировать все, что мы сделали. Добавим в метод
нашего единственного контроллера несколько постов:

Теперь передаем в метод нашего контроллера шаблон
и
массив с постами. В итоге должно получиться так:

Запускаем сервер, проверяем.

Переменные

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

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

{{ foo.bar }}
{{ foo }}

Если атрибуты содержат специальные символы (например, это воспримется,
как оператор минус), в этом случае используйте функцию :

{# Подобное не будет работать foo.data-foo #}
{{ attribute(foo, 'data-foo') }}

Note

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

Если переменная, или атрибут не найден, то в шаблоне это заменится на
значение. Однако если опция установлена как ,
Twig выдаст сообщение об ошибке (см. ).

Реализация

Рассмотрим что будет, когда Twig ищет на уровне PHP:

  • проверяет, что — массив, и bar — ключ в массиве;
  • если нет, и — объект и соответствующие свойство;
  • если нет, и — объект и соответствующий метод
    (даже если конструктор — use );
  • если нет, и — объект, проверяет есть ли метод ;
  • если нет, и — объект, проверяет есть ли метод ;
  • если нет, вернется .

это массив:

  • проверяет, что — массив и bar — существующий в нем ключ;
  • если нет, вернется .

Note

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

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

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

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

Переменные

Вы можете устанавливать значения переменных в блоках кода для этого
используйте тег :

{% set foo = 'foo' %}
{% set foo =  %}
{% set foo = {'foo': 'bar'} %}

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

.. versionadded:: 1.1

Управление пробелами было добавлено в Twig 1.1.

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

Используйте тег для удаления пробелов между HTML тегами:

{% spaceless %}
    div>
        strong>foostrong>
    div>
{% endspaceless %}

{# на выходе будет foo #}

Также можно удалять пробелы для блоков кода:

{% set value = 'no spaces' %}
{#- нет начальных и конечных пробелов -#}
{%- if true -%}
    {{- value -}}
{%- endif -%}

{# выведет 'no spaces' #}

Можно удалять пробелы с одной или другой стороны:

{% set value = 'no spaces' %}
li>    {{- value }}    li>

{# выведет 'no spaces    ' #}

Including other Templates¶

The include function is useful to include a template
and return the rendered content of that template into the current one:

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

By default, included templates have access to the same context as the template
which includes them. This means that any variable defined in the main template
will be available in the included template too:

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

The included template is able to access the variable.

The name of the template depends on the template loader. For instance, the
allows you to access other templates by giving the
filename. You can access templates in subdirectories with a slash:

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

Отладочные опции Twig:

Какие возможности дает включенная опция debug в значение true в sites/default/services.yml?

Во-первых, в исходном html коде страницы все части кода будут обернуты в комментарии с информацией о используемых для вывода шаблонах и всех возможных вариантах именования файлов шаблонов (template suggestions).

Во-вторых, в шаблонах Twig появится возможность использования функцию для вывода отладочной информации о переменных шаблона.
В-третьих, все файлы шаблона будут автоматически перекомпилироваться после любого изменения, внесенного в файл шаблона (смотри опцию auto_reload ниже).
По умолчанию опция установлена в false.

Операторы

Twig позволяет использовать операторы везде. Они работают подобно обычным
операторам PHP, если вы не знаете PHP то у вас не будет с ними сложностей.

Note

Приоритет операторов, сначала идут операторы с наименьшим
приоритетом: , , , , ,
, ,

Литералы

.. versionadded:: 1.5

Поддержка хэш-ключей, имен и выражений была добавлена в Twig 1.5.

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

  • : Все заключенное в одинарные или двойные кавычки
    является строками. Это полезно, когда нужно использовать строки в шаблоне
    (например, в качестве аргументов для вызова функций, фильтров или просто,
    чтобы расширить или подключить шаблон). Строка может содержать разделитель,
    который нужно экранировать обратным слешем () —
    как в примере .

  • / : Целые числа и числа с плавающей точкой записываются
    так как есть. Если есть точка — это float, иначе — integer.

  • : Массивы определяются как набор данных разделенных
    запятыми () и заключенных в квадратные скобки ().

  • : Хеши определяются списком ключей и значений
    разделенными запятой () и заключены в фигурные скобки ().

    {# ключи как строка #}
    { 'foo': 'foo', 'bar': 'bar' }
    
    {# ключи как названия (эквивалентно предыдущему варианту) -- доступно с Twig 1.5 #}
    { foo: 'foo', bar: 'bar' }
    
    {# ключи как число #}
    { 2: 'foo', 4: 'bar' }
    
    {# ключи как выражения (выражения должны быть включены в скобки) -- доступно с Twig 1.5 #}
    { (1 + 1): 'foo', (a ~ 'b'): 'bar' }
  • / : — истина, — ложь.

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

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

{% set foo =  %}

Tip

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

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

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

  • :Складывает два объекта вместе (операнды приводятся к числами).
    выведет .
  • :Вычитает из первого аргумента второй. выведет .
  • :Деление чисел. Возвращает число с плавающей точкой. равнозначно .
  • :Вычисляет целый остаток от деления. выведет .
  • :Делит два числа и возвращает результат целое число. выведет .
  • :Умножение. вернет .
  • :Возводит левый аргумент в степень правого аргумента вернет .

Логические операторы

Вы можете сочетать выражения используя следующие операторы:

  • : Возвращает , если левое и правое значение являются .
  • : Возвращает , если левое или правое значение являются .
  • : Противоположное значение.
  • : Группа выражений.

Note

Twig также поддерживает битовые операторы: (, , and ).

Оператор содержания

Оператор осуществляет проверку на совпадение.

Возвращает , если левое значение содержится в правом:

{# вернет true #}

{{ 1 in  }}

{{ 'cd' in 'abcde' }}

Tip

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

Для отрицания используйте оператор :

{% if 1 not in  %}

{# эквивалентно #}
{% if not (1 in ) %}

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

Оператор проверяет данные на соответствие

{# проверит является ли переменная нечетной #}

{{ name is odd }}

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

{% if loop.index is divisibleby(3) %}

Для отрицания используйте оператор, используйте оператор :

{% if loop.index is not divisibleby(3) %}

{# эквивалентно #}
{% if not (loop.index is divisibleby(3)) %}

Результаты работы можно посмотреть в тестах .

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

.. versionadded:: 1.12.0

Поддержка тернарного оператора была добавлена в Twig 1.12.0.

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

  • : Создает последовательность от левого до правого значения,
    (это просто дополнение синтаксиса для функции )

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

  • : Преобразует все значения в строки и соединяет их.
    вернет
    (предположим, что это ) .

  • , : Получает атрибут объекта.

  • : Тернарный оператор:

    {{ foo ? 'Да' : 'Нет' }}
    
    {# доступно с Twig 1.12.0 #}
    {{ foo ?: 'Нет' }} == {{ foo ? foo : 'Нет' }}
    {{ foo ? 'Да' }} == {{ foo ? 'Да' : '' }}

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

.. versionadded:: 1.5

Поддержка интерполяции строк (подстановки переменных) была добавлена в Twig 1.5.

Подстановка переменных () доступна для любого выражения
находящегося в строке с двойными скобками:

{{ "Привет #{name}! Как дела?" }}
{{ "Дважды два =  #{2*2}" }}

Usage

use DI\Container;
use Slim\Factory\AppFactory;
use Slim\Views\Twig;
use Slim\Views\TwigMiddleware;

require __DIR__ . '/vendor/autoload.php';

// Create Container
$container = new Container();
AppFactory::setContainer($container);

// Set view in Container
$container->set('view', function() {
    return Twig::create('path/to/templates', ['cache' => 'path/to/cache']);
});

// Create App
$app = AppFactory::create();

// Add Twig-View Middleware
$app->add(TwigMiddleware::createFromContainer($app));

// Define named route
$app->get('/hello/{name}', function ($request, $response, $args) {
    return $this->get('view')->render($response, 'profile.html', 
    ]);
})->setName('profile');

// Render from string
$app->get('/hi/{name}', function ($request, $response, $args) {
    $str = $this->get('view')->fetchFromString(
        '

Hi, my name is {{ name }}.

‘,

‘name’ => $args

);
$response->getBody()->write($str);
return $response;
});

// Run app
$app->run();

Without container

use Slim\Factory\AppFactory;
use Slim\Views\Twig;
use Slim\Views\TwigMiddleware;

require __DIR__ . '/vendor/autoload.php';

// Create App
$app = AppFactory::create();

// Create Twig
$twig = Twig::create('path/to/templates', ['cache' => 'path/to/cache']);

// Add Twig-View Middleware
$app->add(TwigMiddleware::create($app, $twig));

// Define named route
$app->get('/hello/{name}', function ($request, $response, $args) {
    $view = Twig::fromRequest($request);
    return $view->render($response, 'profile.html', 
    ]);
})->setName('profile');

// Render from string
$app->get('/hi/{name}', function ($request, $response, $args) {
    $view = Twig::fromRequest($request);
    $str = $view->fetchFromString(
        '

Hi, my name is {{ name }}.

‘,

‘name’ => $args

);
$response->getBody()->write($str);
return $response;
});

// Run app
$app->run();

Как выбрать шаблонизатор?

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

Blade

Синтаксис и функциональность

Blade поддерживает наследование шаблонов, секции, безопасный ввод содержимого и простой синтаксис. Blade разрешает использование PHP внутри шаблонов.

Blade отлично документирован, но документация носит характер обзоров, в то время как более детальная информация содержится на сторонних ресурсах. 

Производительность

Во время теста скорость достигала 100 000 шаблонов в секунду. Но если учитывать обработку шаблонов вместе с загрузкой фреймворка, то скорость около 2 200 шаблонов в секунду. 

Mustache

Синтаксис и функциональность

Шаблоны Mustache не могут содержать логику, поэтому backend-разработчикам приходится реализовывать излишнюю логику, связанную с представлением. 

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

Производительность

Mustache, по очевидным причинам, оказался очень быстрым (6,000 шаблонов в секунду).

Smarty

Синтаксис и функциональность

Синтаксис лаконичен и прост для восприятия. Функционал большой и расширяемый. 

Документация у Smarty хорошо организована. Сайт выглядит немного устаревшим, но это является проблемой. 

Производительность

Smarty довольно быстро обрабатывает некэшируемые шаблоны (9 634 шаблонов в секунду) and ещё быстрее — кэшируемые (57 115 шаблонов в секунду). 

Twig

Синтаксис и функциональность

Twig поставляется с полным набором функций, фильтров, тестов и расширяемых макросов.

Документация отлично организована, информативна и содержит наглядную информацию. Сообщество вокруг Twig большое, ведётся активная разработка на GitHub. Twig используется в Drupal 8, второй по популярности CMS. 

Производительность

Обработка некэшируемых шаблонов происходит со скоростью 4 318 шаблонов в секунду, а кэшированных — 5 982.

Синтаксис и функциональность

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

Производительность

Ввиду того, что фреймворк написан на C, Volt обрабатывает 23 900 шаблонов в секунду и вдвое больше при включении кэширования. 

Рассмотрим фильтры, которые предоставляет сам Twig:

Фильтр batch

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

Результат применения фильтра:

Фильтр convert_encoding

Фильтр convert_encoding преобразует строку из одной кодировки в другую. Первым аргументом является текущая кодировка, вторым — ожидаемая кодировка. Для использования данного фильтра должны быть установлены расширения Iconv или MBstring. В случае, если установлены оба, MBstring используется по умолчанию.

Фильтр date

Фильтр date формирует дату в заданном формате (использует php функцию date()):

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

В Drupal 8 имеется свой фильтр форматирования даты .

Фильтр date_modify

Фильтр date_modify изменяет дату по заданному модификатору. Фильтр принимает аргументом строку (она должна быть в формате, поддерживаемом php функцией strtotime()) или экземпляр php класса DateTime. Его можно легко объединить с фильтром date для форматирования даты.

Фильтр default

Фильтр default возвращает переданное значение по умолчанию, если значение не определено или пусто, в противном случае значение переменной:

При вызове методов также можно передавать значение по умолчанию и назначать значение по умолчанию возвращаемому результату:

Фильтр escape

Фильтр escape экранирует строку для вывода (использует php функцию htmlspecialchars() для html). Он поддерживает различные настройки в зависимости от контекста шаблона. По умолчанию экранируется HTML:

Для удобства работы с фильтром у него есть псевдоним:

Фильтр escape поддерживает следующие методы экранирования:

  • html — экранирует строку для контекста HTML (по умолчанию);
  • js — экранирует строку для контекста JavaScript;
  • css — экранирует строку для контекста CSS;
  • url — экранирует строку для URI;
  • html_attr — экранирует строку для контекста атрибута HTML.

Таким образом экранируется JavaScript:

В Drupal 8 имеется свой собственный фильтр .

Фильтр first

Фильтр first возвращает первый элемент массива или первый символ строки:

Применяется также и к объектам, являющимся экземпляром класса, имплементирующего интерфейс Traversable.

Фильтр join

Фильтр join объединяет элементы массива в строку:

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

В Drupal 8 рекомендуется использовать более безопасный фильтр .

Фильтр last

Фильтр last возвращает последний элемент массива или последний символ строки:

Применяется также и к объектам, являющиеся экземпляром класса, имплементирующего интерфейс Traversable.

Фильтр number_format

Фильтр number_format позволяет форматировать числа (использует php функцию number_format()):

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

Фильтр raw

Фильтр raw отмечает значение переменной как «безопасное», что означает, что в блоке экранирования autoescape эта переменная будет выведена как не экранируемая:

Фильтр reverse

Фильтр reverse возвращает массив с элементами в обратном порядке или переворачивает строку задом наперед:

Для массивов числовые ключи не сохраняются. Если передать в аргумент true, то ключи будут сохранены. Не числовые ключи не подвержены этой опции и всегда сохраняются:

Фильтр round

Фильтр round округляет числа с указанной точностью. Фильтр имеет два необязательных аргумента, первый из которых определяет точность (по умолчанию 0), а второй — метод округления (по умолчанию common):

  • common — округление в большую или меньшую сторону в зависимости от дробной части (округляет значение, отсекая дробную часть). Если дробная часть равна 1,5 измениться на 2 и -1,5 на -2;
  • ceil — округляет в большую сторону;
  • floor — округляет в меньшую сторону.

Фильтр slice

Выбирает срез массива или возвращает подстроку (использует PHP функцию array_slice() для массивов и substr() для строк). Принимает 2 аргумента: start — начальный индекс массива или позиция строки (начинается с 0, возможны отрицательные значения) и length — количество элементов массива или символов строки.

Фильтр striptags

Фильтр striptags удаляет html теги и заменяет множественные пробелы на 1 пробел (использует PHP функцию strip_tags()), а теги, переданные в аргумент не вырезает:

Ссылка на основную публикацию