Синтаксис twig. Что такое шаблонизатор Twig и зачем он нужен? Docblock и комментарии

Twig 2 - Twig for Template Designers

Twig для дизайнеров шаблонов

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

конспект

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

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

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

My Webpage

My Webpage

{{ a_variable }}

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

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

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

  • Textmate через пакет Twig
  • Vim через плагин синтаксиса Jinja или плагин vim-twig
  • Netbeans через плагин синтаксиса Twig (до 7.1, родной по 7.2)
  • PhpStorm (родной от 2.1)
  • Eclipse через плагин Twig
  • Возвышенный текст через пакет Twig
  • GtkSourceView через определение языка Twig (используется gedit и другими проектами)
  • Coda и SubEthaEdit через синтаксический режим Twig
  • Coda 2 через другой синтаксический режим Twig
  • Комодо и Комодо Редактировать через режим Twid подсветки / синтаксиса
  • Блокнот ++ через Notepad ++ Twig Highlighter
  • Emacs через web-mode.el
  • Atom через PHP-ветку для атома
  • Код Visual Studio через пакет Twig

Реализация

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

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

foo["bar"] с другой стороны, работает только с массивами PHP:

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

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

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

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

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

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

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

фильтры

Переменные могут быть изменены фильтрами . Фильтры отделяются от переменной символом (|) и могут иметь необязательные аргументы в круглых скобках. Несколько фильтров могут быть скованы цепью. Выход одного фильтра применяется к следующему.

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

{{ name|striptags|title }}

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

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

Чтобы применить фильтр к разделу кода, оберните его в тег filter :

{% filter upper %} This text becomes uppercase {% endfilter %}

Members

    {% for user in users %}
  • {{ user.username|e }}
  • {% endfor %}
{{ user.username|e }}

По умолчанию фильтр-победитель использует 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, чтобы не повторять себя.

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

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

Оператор in выполняет тест на герметичность.

Он возвращает true если левый операнд содержится справа:

{# returns true #} {{ 1 in }} {{ "cd" in "abcde" }}

Наконечник

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

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

{% if 1 not in %} {# is equivalent to #} {% if not (1 in ) %}

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

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

{# 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")) %}

В данной статье я расскажу вам, что такое шаблонизатор Twig , и чем он может помочь веб-разработчику.

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

Конечно, мы можем взять представление, дать ему расширение.php , добавить туда код на HTML и CSS , как вариант. Но данное решение не подходит для работы среди разработчиков с более-менее четким разделением сфер ответственности. Т.е. если у вас есть своя веб-студия или вы собираетесь таковую создать (тут вам может пригодиться мой курс ), то верстальщик не обязательно должен знать PHP или наоборот. И поэтому, чтобы не загрязнять код шаблона конструкциями языка PHP и сделать разработку проще, стоит использовать PHP шаблонизатор Twig . Но, разве сам PHP не шаблонизатор можете справедливо спросить вы? Ответ здесь не однозначен – и да, и нет.

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

Привет " . $name. "

"; ?>

Привет {{ name }}

Опытные программисты знают, что PHP многословный язык , и эта избыточность становится еще более очевидной, при формировании HTML контента. А современные системы шаблонизации , наоборот, пытаются уйти от излишней избыточности кода, при этом добавляя еще и свою функциональность поверх средств самого языка. Конечно же, вопросы безопасности и отладки также не обходятся стороной, и им уделяется пристальное внимание. Потому, то я и захотел вам рассказать об одном таком шаблонизаторе PHP – Twig.

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

Устанавливается Twig двумя путями. Можно использовать или архив с исходным кодом, или использовать менеджер пакетов . Но последний предпочтительнее.

Composer require twig/twig

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

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

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

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

Но, по умолчанию, в Symfony используется именно шаблонизатор Twig.

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

Если мы с вами вспомним модель MVC (модель - вид - контроллер), о которой мы с вами говорили несколько ранее, то шаблонизатор - это то, что относится к части "Вида".

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

Файл шаблонизатора - это обычный текстовый файл. Для Twig этот файл имеет 2 расширения.

Это означает то, что этот файл у нас содержит HTML-разметку и во вторых этот файл является служебным файлом шаблонизатора Twig.

По сути, в этом файле у нас содержаться 2 части: обычный html-код с простыми html-тэгами, встроенные стили CSS, встроенный Javascript-код и.т.д.

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

Данные на сервере могут меняться и автоматически они также меняются в twig файле. Т.е. мы получили html-страницу, которая содержит какие-то данные с веб-сервера.

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

Т.е. шаблонизатор - это что-то вроде некого шаблона и в этот шаблон мы можем передавать некие переменные, которые зависят от состояния нашего сервера.

Поэтому, шаблонизатор и происходит от слова "шаблон". Там содержится какая-то шаблонная страница, шаблонный html-код и в него вставляются переменные данные.

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

А контроллер уже возвращает готовый html-код тому посетителю сайта. который его запросил.

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

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

Примеры обращений:

{% if order.fromApi %} {{ order.getNickName() }} {% endif %}

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

Пример обращения:

{% if order.getDeliveryType().getCode() == "russian-post" %} {{ order.trackNumber }} {% endif %}

Отмена генерации twig-шаблона

Могут возникать ситуации, когда требуется отменить генерацию шаблона. Например, мы на триггере хотим отправлять письмо с товарными рекомендациями, но, если никаких рекомендаций для клиента не найдено, то генерацию шаблона письма и его отправку производить не надо. Для отмены следует использовать тег {% cancel %} .

Пример использования:

{% set recom = best_selling_products() %} {% if recom|length > 0 %} {# выводим рекомендуемые товары #} {% else %} {% cancel %} {% endif %}

Если срабатывает {% cancel %} , то в это будет зафиксировано:

В теге также можно указать сообщение, которое будет зафиксировано в .

Пример использования с указанием сообщения:

{% set recom = best_selling_products() %} {% if recom|length > 0 %} {# выводим рекомендуемые товары #} {% else %} {% cancel "Не найдено рекомендованных товаров" %} {% endif %}

В журнале действий в этом случае будет следующее:

В случае отмены генерации шаблона письма, SMS или печатной формы, которые генерируются вручную, пользователю будет выведено сообщение, указанное в теге {% cancel %} .

Часто возникающие вопросы

1. Как вывести в шаблоне значение пользовательского поля заказа

Для вывода данных из пользовательского поля используйте метод getCustomField . Пример:

{{ order.getCustomField("some_code") }}

В примере some_code - символьный код пользовательского поля.

2. Ошибка при попытке вывести поле заказа, содержащее дату

Речь о проблеме в случае, когда вы видите следующее сообщение об ошибке:

Calling "__tostring" method on a "DateTime" object is not allowed

Дело в том, что при выводе в twig-шаблоне полей заказа (или клиента), которые содержат дату, требуется применять фильтр date , чтобы указать формат вывода даты.

{{ order.createdAt|date("d.m.Y") }}

3. Ошибка при попытке вывести поле, содержащее интервал дат

Речь о проблеме в случае, когда вы видите подобное сообщение об ошибке:

Calling "m" property on a "DateInterval" object is not allowed

Дело в том, что при выводе в twig-шаблоне полей, которые содержат интервал дат, требуется применять фильтр date , чтобы указать формат вывода.

{{ period|date("%m") }}

Подробное описание форматов вывода DateInterval можно найти по ссылке: http://php.net/manual/ru/dateinterval.format.php

4. Как вывести текущую дату

Для вывода текущей даты используйте фильтр date следующим образом:

{{ "now"|date("d.m.Y") }}

5. Как вывести штрихкод в печатной форме

Вы можете воспользоваться сервисом http://www.barcodes4.me/apidocumentation . Пример подстановки данных:

- "компилирующий обработчик шаблонов с открытым исходным кодом, написанный на языке программирования PHP. Armin Ronacher написал Twig в 2008 году для платформы блогов Chyrp. Он больше не возвращался к разработке и в большей степени занимался разработкой на Python. Синтаксис языка шаблонов Twig берёт начало от движков шаблонов Jinja и Django, первый из которых также создан Ронакером. Идею данного шаблонизатора развивает и поддерживает Fabien Potencier, ведущий разработчик и идеолог фреймворка Symfony, в котором Twig используется по умолчанию." (https://ru.wikipedia.org/wiki/Twig).

Все Twig шаблоны в Drupal 8 компилируются в php файлы и хранятся в каталоге sites/default/files/php/twig/. Файлы шаблонов при этом кешируются для повторного использования и хранятся в файловой системе для улучшения производительности, перекомпилируются только при очистке Twig кеша.

Все шаблоны в модулях и темах должны находиться в каталоге /templates .

Почему Twig? Во-первых, он более безопасный. В шаблонах Drupal 7 часто выводились неочищенные данные и это в принципе понятно, так как верстальщик не должен следить за работой программиста, который банально мог забыть пропустить данные из форм через check_plain(). В шаблонах же Drupal 8 переменные будут по-умолчанию экранироваться. Кроме этого многие наверняка в шаблонах наблюдали Sql запросы и прочие изыски логики приложения, но в Twig шаблонах это будет исключено.

Во-вторых, в Twig есть очень интересная особенность - наследование шаблонов. Теперь достаточно создать базовый родительский шаблон и затем при создании дочернего шаблона в теге extends указать родительский шаблон. К примеру чтобы создать дочерний шаблон ноды нужно в нем прописать:


{% extends "node.html.twig" %}

Рассмотрим наследование на примере шаблонов для блока. Базовый родительский шаблон для блока block.html.twig содержит примерно такой код

{{ title_prefix }} {% if label %} {{ label }} {% endif %} {{ title_suffix }} {% block content %}

{{ content }}
{% endblock %}

При этом содержимое тега block можно в дочернем шаблоне переписать. Рассмотрим код шаблона для блока с формой поиска block--search-form-block.html.twig

{% extends "block.html.twig" %} {% block content %} {{ parent() }}

{% endblock %}

Дочерний шаблон будет содержать всю разметку block.html.twig за исключением переписанного содержимого внутри тега block:

{% block content %}{% endblock %}

Рассмотрим основные отличия PHPTemplate и Twig на примерах

Именование файлов шаблонов и функций

PHPTemplate файл шаблона: node--article.tpl.php
Twig файл шаблона: node--article.html.twig

Большинство theme_ функций сейчас вынесено в шаблоны (огромный плюс)
PHPTemplate функция: theme_node_links()
Twig файл шаблона: node-links.html.twig

Docblock и комментарии

Docblock в PHPTemplate:

{# /** * @file * File description */ #}

Комментарии вместо стандартных php комментариев теперь выглядят так:

{# Twig комментарий #}

Работа с переменными

Вывод переменных:

{{ content }}

Вывод свойств объектов и элементов массивов:

body; ?>

{{ content.body }}

Вывод элементов массива с хешем в имени ключа

{{ item["#item"].alt }}

Запись в переменную:

field_image; ?>

{% set image = content.field_image %}

Запись в переменную массива:

{% set classes = ["class1", "class2", "class3"] %}

Условия

comments): endif; ?>

{% if content.comments %} {% endif %}

comments)): endif; ?>

{% if content.comments is not empty %} {% endif %}

comments)): endif; ?>

{% if content.comments is defined %} {% endif %}

0): endif; ?>

{% if count > 0 %} {% endif %}

Циклы

{% for user in users %} {% endfor %}

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

Twig позволяет убирать пробелы из вывода с помощью символа - в начале и/или конце структуры {{ }} для вывода переменных.

И в начале, и в конце:

{{- block.content -}}
{# Результат:
контент
#}

Только в начале:

{{- block.content }}
{# Результат:
контент
#}

Только в конце:

{{ block.content -}}
{# Результат:
контент
#}

Официальная документация по Twig в Drupal 8