Синтаксис twig. Что такое шаблонизатор Twig и зачем он нужен? Docblock и комментарии
Twig 2 - Twig for Template Designers
Twig для дизайнеров шаблонов
Этот документ описывает синтаксис и семантику механизма шаблона и будет наиболее полезен в качестве ссылки на те, которые создают шаблоны Twig.
конспект
Шаблон - это просто текстовый файл. Он может генерировать любой текстовый формат (HTML, XML, CSV, LaTeX и т. Д.). У него нет определенного расширения, .html или.xml просто отлично.
Шаблон содержит переменные или выражения , которые заменяются значениями при оценке шаблона и тегами , которые управляют логикой шаблона.
Ниже приведен минимальный шаблон, который иллюстрирует несколько основ. Ниже мы расскажем о следующих деталях:
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 %}
По умолчанию фильтр-победитель использует 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 содержит примерно такой код
{{ label }}
{% endif %} {{ title_suffix }} {% block content %}При этом содержимое тега block можно в дочернем шаблоне переписать. Рассмотрим код шаблона для блока с формой поиска block--search-form-block.html.twig
{% extends "block.html.twig" %} {% block content %}
Дочерний шаблон будет содержать всю разметку 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 комментарий #}
Работа с переменными
Вывод переменных:
Вывод свойств объектов и элементов массивов:
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 позволяет убирать пробелы из вывода с помощью символа - в начале и/или конце структуры {{ }} для вывода переменных.
И в начале, и в конце:
Только в начале:
Только в конце:
Официальная документация по Twig в Drupal 8