Фильтры
Переменные могут быть изменены с помощью фильтров. Фильтры отделяются от переменных
прямой чертой () и могут содержать параметры в круглых скобках. Фильтры могут
применяться по цепочке. Тогда результат одного фильтра передается к следующему.
Следующий пример удаляет все HTML-теги из и преобразует в верхний
регистр первый символ каждого слова:
{{ name|striptags|title }}
У фильтров, которые принимают аргументы, есть круглые скобки вокруг аргументов.
В этом примере, добавится после list запятая :
{{ list|join(', ') }}
Чтобы применить фильтр к блоку кода — оберните его тегом
:
{% filter upper %} Этот текст будет в верхнем регистре {% endfilter %}
Перейдите на страницу , чтобы узнать больше о
встроенных фильтрах.
Отладка шаблонов¶
Symfony предоставляет несколько утилит для помощи с отладкой проблем в ваших шаблонах.
Проверка соблюдения стандартов кодирования шаблонов Twig
Команда проверяет, чтобы в ваших шаблонах Twig не было никаких синтаксических
ошибок. Полезно выполнять ее до запуска вашего приложения в производство (например, на вашем
сервере непрерывной интеграции):
1 2 3 4 5 6 7 8 9 |
# проверить все шаблоны приложения $ php bin/console lint:twig # вы такжже можете проверить каталоги и отдельные шаблоны $ php bin/console lint:twig templates/email/ $ php bin/console lint:twig templates/article/recent_list.html.twig # вы также можете увидеть устаревший функции, используемые в ваших шаблонах $ php bin/console lint:twig --show-deprecations templates/email/ |
Исследование информации Twig
Команда перечисляет всю доступную информацию о Twig (функции,
фильтры, глобальные переменные и т.д.). Она полезна для проверки того, правильно
ли работают ваши пользовательские расширения Twig,
и проверки функций Twig, добавленных при :
1 2 3 4 5 6 7 8 |
# перечислить общую информацию $ php bin/console debug:twig # отфильтровать вывод по любому ключевому слову $ php bin/console debug:twig --filter=date # передать путь шаблона, чтобы указать физический файл, который будет загружен $ php bin/console debug:twig @Twig/Exception/error.html.twig |
Сервер дампов¶
New in version 4.1: Сервер дампов появился в Symfony 4.1.
Функция выводит своё содержимое в то же окно браузера или
консольный терминал, что и ваше приложение. Иногда смешение настоящего вывода
с выводом отладочной информации может запутывать. Поэтому этот компонент предоставляет
сервер для сбора всей отладочной информации.
Запустите сервер командой и когда вы будете вызывать
, отладочная информация не будет отображаться в потоке вывода, а отправится на этот
сервер, который будет отображать это в своей конслоли или HTML-файле:
1 2 3 4 5 6 |
# отображает отладочную информацию в консоли: $ ./bin/console server:dump Server listening on tcp://0.0.0.0:9912 # сохраняет отладочную информацию в файле используя формат HTML: $ ./bin/console server:dump --format=html > dump.html |
Наследование шаблонов
Самая мощная часть Twig — это наследование шаблонов. Наследование шаблонов
позволяет вам создать основной «скелет» шаблона, который содержит все элементы
вашего сайта и определить теги blocks, которые будут перезаписаны в дочерних
шаблонах.
Звучит сложно, на самом деле все просто. Проще всего разобраться с наследованием
на примере.
Давайте создадим основной шаблон, , который определит простой
«скелет» HTML-документа, который можно использовать для простой страницы с
двумя колонками:
<!DOCTYPE html> <html> <head> {% block head %} <link rel="stylesheet" href="style.css" /> <title>{% block title %}{% endblock %} - Мой сайт</title> {% endblock %} </head> <body> <div id="content">{% block content %}{% endblock %}</div> <div id="footer"> {% block footer %} © Copyright 2011 by <a href="http://domain.invalid/">you</a>. {% endblock %} </div> </body> </html>
В этом примере, тег определяет четыре блока, которые
будут заполнены в дочернем шаблоне. Все теги говорят шаблонизатору,
что они могут быть переопределены в дочернем шаблоне.
Дочерний шаблон может выглядеть следующим образом:
{% extends "base.html" %} {% block title %}Главная{% endblock %} {% block head %} {{ parent() }} <style type="text/css"> .important { color: #336699; } </style> {% endblock %} {% block content %} <h1>Главная</h1> <p class="important"> Приветствую на своем потрясном сайте! </p> {% endblock %}
Тег ключевой здесь. Он сообщает шаблонизатору,
что этот шаблон «расширяет» другой шаблон. Когда шаблонизатор обрабатывает шаблон,
он первым делом смотрит на родительский шаблон. Тег «extends« должен
быть первым в шаблоне.
Обратите внимание, что так как в дочернем шаблоне не определен блок ,
то он берется из родительского. Используя функцию , можно отобразить содержание
родительского блока
Она возвращает первоначальное содержание родительского блока:
Используя функцию , можно отобразить содержание
родительского блока. Она возвращает первоначальное содержание родительского блока:
{% block sidebar %} <h3>Оглавление</h3> ... {{ parent() }} {% endblock %}
Tip
Страница документации описывает более
продвинутые функции, такие как вложенности блоков, область применения,
динамическое и условное наследование.
Note
Twig также поддерживает множественное наследование с использованием
тега .
Язык шаблонов Twig¶
Язык шаблонов Twig позволяет вам писать емкие и читаемые шаблоны, которые более
дружелюбны по отношению к веб-дизайнерам и, во многих смыслах, более мощные, чем
щаблоны PHP. Посмотрите на следующий пример шаблона Twig. Даже если это первый раз,
когда вы видите Twig, вы скорее всего понимаете большую часть:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<!DOCTYPE html> <html> <head> <title>Welcome to Symfony!</title> </head> <body> <h1>{{ page_title }}</h1> {% if user.isLoggedIn %} Hello {{ user.name }}! {% endif %} {# ... #} </body> </html> |
Синтаксис Twig основывается на следующих трех конструкциях:
-
, используется для отображения содержания переменной или результата
оценки выражения; - , используется для выполнения некоторой логики, вроде условности или цикла;
-
, используется для добавления комментариев в шаблон (в отличие от комментариев
HTML, эти коммментарии не добавляются на отображенную страницу).
Вы не можете запустить PHP-код внутри шаблонов Twig, но Twig предоставляет утилиты для
выполнения некоторой логики в шаблонах. Например, фильтры изменяют содержание до его
отображения, например фильтр преобразует содержание в заглавные буквы:
1 |
{{ title|upper }} |
Twig поставляется с длинным списком , и , которые доступны
по умолчанию. В приложениях Symfony вы можете также использовать эти
фильтры и функции Twig, определенные Symfony и вы можете
создавать собственные функции и фильтры Twig.
Twig быстр в (так как
шаблоны компилируются в PHP и кешируются автоматически), но удобнее использовать
окружение (потому что шаблоны повторно компилируются автоматически при
их изменении).
Фильтры Twig
Еще одно весомое преимущество Twig – наличие ряда весьма полезных и простых в использовании фильтров. Проще всего рассмотреть данные фильтры на примере:
Это вернет значение переменной shape заглавными буквами. При необходимости можно объединить несколько фильтров:
Этот фильтр обрезает пробелы в начале и в конце значения переменной. Кроме того, фильтры можно применять на целый блок:
Данное выражение переведет все в пределах блока фильтра в верхний регистр.
В целом, Twig предлагает большое количество удобных фильтров, с которыми можно подробнее ознакомиться . Некоторые фильтры даже принимают аргументы (например, фильтр date, позволяющий задать формат, в котором нужно отображать переменную date).
Заменить php-шаблоны на twig-шаблоны
Мы можем для этого использовать два хука template_redirect или template_include. Первый отрабатывает раньше и затем появляются данные в global $wp_query, $post и т.д. Попробуем переопределить шаблоны для всех страниц:
class Controller extends Twig_Controller { public function __construct() { parent::__construct( [ get_template_directory() . '/views/' ] ); add_filter( 'template_include', ); } public function template_include( string $template ) { if ( is_page() ) { global $post; $this->render( 'page', ); } } }
Теперь вместо page.php будет подключаться page.twig. Как поменялся синтаксис?
Было:
<?php get_header() ?> <div id="primary" class="content-area"> <main id="main" class="site-main"> <div class="entry-header"> <h1><?php the_title() ?></h1> <div class="corner__bottom corner--double"></div> </div><!-- .entry-header --> <article id="post-` post`.`ID `" <?php post_class( $class ) ?>> <div class="entry-content"> <?php the_content() ?> </div><!-- .entry-content --> </article><!-- #post-<?php the_ID() ?> --> </main> </div> <?php get_footer() ?>
Стало:
{% include 'header.twig' %} <div id="primary" class="content-area"> <main id="main" class="site-main"> <div class="entry-header"> <h1>` post`.`post_title `</h1> </div><!-- .entry-header --> <article id="post-` post`.`ID `" {% do action('mx_post_class') %}> <div class="entry-content"> {% do filter('the_content', post.post_content ) %} </div><!-- .entry-content --> </article><!-- #post-` post`.`ID ` --> </main> </div> {% include 'footer.twig' %}
Особо ничего не изменилось, но теперь данные во вьюшку могут попасть только через наш контроллер. Никаких лишних данных там не будет и соответсвенно основная задача шаблонизаторов выполняется.
Все нужные данные на фронте можно добавить в template_include. Т.к. наш контроллер мы добавили на хук template_include у нас уже есть global $wp_query, $post и остальные «прелести» WordPress’а.
1 ответ
Лучший ответ
Есть (как минимум) два способа сделать это без расширения Twig. Третий вариант — расширить Twig, создав, например, функция Twig. Я бы, наверное, выбрал первый способ (с использованием фильтра ).
Используя фильтр
Как указал @The_Unknown, вы также можете использовать фильтр :
Вы можете не передавать фильтру значение по умолчанию, и даже опустить круглые скобки. Тогда значение по умолчанию будет пустой строкой (что неверно). Т.е. эти два равны и действительны:
Какой бы стиль вы ни выбрали (по умолчанию , значение или скобки не указываются), придерживайтесь его. Быть последовательным.
См. TwigFiddle для демонстрации того, что истинные значения оцениваются как , а ложные значения оцениваются как (на основании приведенной ниже таблицы).
Установив на
Установив для переменной среды значение , вы можете пропустить часть и сделать только . Как описано в :
Установите для переменной значение при создании экземпляра :
Если не определено, то , очевидно, равно . На странице документации тега описан крайний случай. правила для определенных переменных:
См. TwigFiddle для демонстрации ( установлен на за «Дополнительные параметры. .. «ссылка в шапке).
Расширяя Twig
(Отказ от ответственности: я написал этот подход до того, как @The_Unknown указал, что также можно использовать фильтр .)
Если идея установки на слишком общая, вы также можете расширить Twig. Я бы сказал, что лучше установить на , чтобы избежать случайных ошибок, вызванных, например, опечатки в именах переменных, поэтому этот подход может быть лучше.
Я не думаю, что вы можете создать фильтр для этого, поскольку неопределенная переменная все равно вызовет исключение. Вы можете создать собственный тег, тест или расширение (см. Расширение Twig a> о способах расширения Twig); Я собираюсь создать настраиваемую функцию, поскольку это, вероятно, самый простой подход.
Часть здесь важна, так как тогда у вас будет доступ к , который содержит переменные, присутствующие в текущем контексте. (Вы можете, например, поставить над оператором возврата, чтобы увидеть его самостоятельно.)
Если вы хотите, чтобы поддерживал одновременную проверку нескольких переменных, вы можете сделать это:
Затем в Twig вы можете:
Вы можете проверить в функции , являются ли аргументы строками или чем-то еще, а затем действовать соответствующим образом. ожидает, что первый аргумент будет либо строкой, либо целым числом.
17
Matias Kinnunen
20 Янв 2018 в 08:37
Синтаксис Twig
Шаблон Twig имеет несколько ключевых компонентов, которые помогают ему понять, что именно вы хотели бы сделать. К ним относятся теги, фильтры, функции и переменные.
Давайте более подробно рассмотрим эти важные инструменты и то, как они могут вам помочь создать невероятный шаблон.
Теги
Теги говорят Твигу, что ему нужно делать. Он позволяет вам установить, какой код Twig должен обрабатывать, а какой код он должен игнорировать во время оценки.
Существует несколько различных типов тегов, и каждый из них имеет свой собственный специфический синтаксис, который отличает их друг от друга.
Комментарии
Теги комментариев (`{#Insert Comment Here#}’) используются для установки комментариев, которые существуют в файле шаблона Twig, но фактически не видны конечному пользователю. Они удаляются во время парсинга, не анализируются и не выводятся.
Хорошо использовать эти теги для объяснения того, что делает конкретная строка кода или команда, чтобы другой разработчик или дизайнер в вашей команде мог быстро прочитать и понять.
Вот пример тега комментария, который вы найдете в файле шаблона Twig:
Выходные теги
Выходные теги (‘` Insert Output Here «) будут оценены и добавлены к сгенерированному выходу. Это место, где вы можете поместить все, что хотите, чтобы появиться на переднем конце, или в каком-то другом сгенерированном контенте.
Вот пример выходных тегов, используемых в шаблоне Twig:
Переменная была вставлена в эту строку и будет показана конечному пользователю как , так как было значение переменной имени.
Очень важно включить параметр в или не забыть экранировать каждую переменную в файлах шаблонов с помощью фильтра , чтобы защитить сайт от XSS-атак. Для безопасного HTML-контента используйте фильтр
Теги действий
Экшн-теги — это путеводители в мир веток. Эти теги на самом деле что-то делают, в отличие от других, которые либо передают что-то, либо сидят сложа руки в исходном коде, ожидая, пока дизайнер прочитает его.
Теги действий задают переменные, цикл через массивы и условия тестирования. Ваши и заявления сделаны с использованием этих меток.
Вот как может выглядеть тег действия в шаблоне Twig:
Первоначальный тег действия устанавливает час как текущий час в 24-часовом формате. Это значение затем используется для определения, находится ли оно между 9 утра и 5 вечера. Если это так, то отображается . Если это не так, то вместо этого отображается .
Очень важно, чтобы метки не перекрывали друг друга. Вы не можете поместить выходной тег внутри тега действия или наоборот
Фильтры
Фильтры полезны, особенно когда вы используете выходные теги для отображения данных, которые могут быть отформатированы не так, как вы хотите.
Допустим, значение переменной может включать нежелательные SGML/XML тэги. Вы можете отфильтровать их, используя код, приведенный ниже:
Функции могут генерировать контент. За ними, как правило, следуют аргументы, которые появляются в скобках, помещаемых непосредственно после вызова функции. Даже если аргумент отсутствует, функция все равно будет иметь скобки , расположенные непосредственно после нее.
Функция dump()¶
Компонент VarDumper создаёт глобальную функцию , которую вы
можете использовать вместо, например. . Используя
её, вы получаете:
- Специализированный просмотр по объектам и источникам, чтобы, к
примеру, отфильтровать внутренние объекты Doctrine при сбросе одной
сущности прокси, или получить больше информации об открытых с помощью
файлах; - Конфигурируемые форматы вывода: вывод HTML или цветной командной строки;
- Возможность сбрасывать внутренние ссылки, мягкие (объекты или источники)
или жёсткие ( в свойствах массивов или объектов). Повторяемое появление
одного и того же объекта/масива/истоничка не будут больше появляться снова и
снова. Более того, вы сможете исследовать структуру ссылок ваших данных; - Возможность оперировать в контексте обработчика буферизации вывода.
Например:
require __DIR__.'/vendor/autoload.php'; // создать переменную, которая может быть чем угодно! $someVar = ...; dump($someVar); // dump() возвращает переданное значение, чтобы вы могли сбросить объект и продолжать использовать его dump($someObject)->someMethod();
По умолчанию, формат вывода и направление выбираются исходя из вашего текущего
PHP SAPI:
- В командной строке (CLI SAPI), вывод пишется в . Это может быть
удивительно для некоторых, так как это обходит механизм буферизации вывода
PHP; - В других SAPI, сбросы пишутся в виде HTML в обычном выводе.
Note
Если вы хотите поймать вывод сброса в виде строки, пожалуйста, прочтите
продвинутую документацию, которая
содержит такие примеры. Вы также узнаете, как изменять формат или перенаправлять
вывод туда, куда вам нужно.
Tip
Для того, чтобы функция всегда была доступна при выполнении любого
PHP кода, вы можете установить её на вашем компьютере глобально:
- Запустите ;
- Добавьте
к вашему файлу ; - Иногда запускайте , чтобы
иметь последние исправления багов.
Как работает Twig?
Twig работает, убирая все фокус-покус из дизайна шаблона. Шаблоны — это, в основном, просто текстовые файлы, содержащие переменные или выражения, которые при оценке шаблона заменяются значениями.
Теги также являются важной частью файла шаблона, так как они контролируют логику самого шаблона. Twig имеет два основных языковых ограничения:
Twig имеет два основных языковых ограничения:
- выводит результат вычисления выражения;
- выполняет инструкции.
Вот базовый шаблон, созданный с помощью Twig:
В этом примере мы устанавливаем заголовок сайта так же, как и для любой стандартной веб-страницы. Разница в том, что мы смогли использовать простой синтаксис Twig для представления имени автора и создания динамического списка типов элементов.
Шаблон сначала загружается, а затем передается через lexer, где его исходный код маркируется и разбивается на мелкие кусочки. В этот момент синтаксический анализатор принимает токены и превращает их в абстрактное синтаксическое дерево.
Как только это делается, компилятор превращает это в PHP-код, который затем может быть оценен и отображен пользователю.
Twig также может быть расширен для добавления дополнительных тегов, фильтров, тестов, операторов, глобальных переменных и функций. Более подробную информацию о расширении Twig можно найти в его официальной документации.
Добавление и наследование шаблонов
Twig обладает очень важной функцией, которая позволяет добавить шаблон в другой шаблон. Например:. Этот оператор загрузит файл header.html и воспроизведет его в текущем контексте шаблона
Это означает, что файл получит доступ ко всем переменным, находящимся в шаблоне. Благодаря этой особенности Twig позволяет хранить несколько файлов в гораздо более чистом виде
Этот оператор загрузит файл header.html и воспроизведет его в текущем контексте шаблона. Это означает, что файл получит доступ ко всем переменным, находящимся в шаблоне. Благодаря этой особенности Twig позволяет хранить несколько файлов в гораздо более чистом виде.
Кроме того, Twig имеет еще одну более мощную функцию – наследование шаблонов. Это позволяет создавать шаблоны, в которых сначала нужно определить блоки, а затем расширить их другими шаблонами, которые либо переопределяют контент по умолчанию этих блоков, либо добавляют в них новый контент. Рассмотрим эту функцию на примере.
Шаблон А (layout.html) содержит следующее (не забывайте, это всего лишь пример):
Как видите, в уже определенных блоках нет никакого контента. При желании его можно добавить, но можно также расширить этот шаблон при помощи шаблона В и добавить контент в эти блоки:
Как видите, шаблон В расширяет шаблон А (в целом, он заполняет шаблон А и воспроизводит его на странице), а также заполняет его заданные блоки, которые в были пусты. Если бы блоки в шаблоне А были заполнены каким-то контентом, шаблон B перезаписал бы этот контент. Чтобы добавить контент к уже существующему контенту, а не перезаписывать его, нужно использовать формат:
Таким образом, блок mainContent загружает контент родительского шаблона, воспроизводит его и добавляет еще немного контента ниже.
Некоторые ключевые моменты
При расширении шаблона блок extends должен быть первым блоком страницы. Также в таком случае нельзя оставлять контент вне блоков, определенных в расширяемом шаблоне. Поэтому весь контент шаблона В должен входить в один из блоков, определенных в шаблоне А.
Чтобы получить более подробную информацию о наследовании шаблонов, обратитесь к документации Twig.
Больше о переменных форм¶
Tip
Чтобы увидеть полный список переменных, см.: .
Почти в каждой функции Twig выше, финальный аргумент — это массив “переменных”,
используемых при отображении одной части формы. Например,следующее будет отображать
“виджет” для поля и изменять его атрибуты, чтобы включать специальный класс:
1 2 |
{# отобразить виджет, но добавить к нему класс "foo" #} {{ form_widget(form.name, { 'attr' {'class' 'foo'} }) }} |
Цель этих переменных — что они делают и откуда они берутся — может быть ясна
не сразу, но они очень мощные. Каждый раз, когда вы отображаете часть вашей
формы, блок, отображающий её, использует несколько переменных. По умолчанию,
эти блоки живут внутри form_div_layout.html.twig.
Рассмотрите в качестве примера:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
{% block form_label %} {% if not compound %} {% set label_attr = label_attr|merge({'for' id}) %} {% endif %} {% if required %} {% set label_attr = label_attr|merge({ 'class' (label_attr.class|default('') ~ ' required')|trim }) %} {% endif %} {% if label is empty %} {% set label = name|humanize %} {% endif %} <label {% for attrname, attrvalue in label_attr -%} {{ attrname }}="{{ attrvalue }}" {%- endfor %} > {{ label|trans({}, translation_domain) }} </label> {% endblock form_label %} |
Этот блок использует несколько переменных: , ,
, , и . Эти переменные
были сделаны доступными системой отображения форм. Но, что важнее, это
переменные, которые вы можете переопределить вызвав (так как
в этом примере вы отображаете ярлык).
Точные переменные доступные для переопределения зависят от того, какую часть
формы вы хотите отобразить (например, ярлык или виджет), и какое поле вы
отображаете (например,виджет имеет дополнительную опцию ).
Если вы ознакомитесь и привыкнете к form_div_layout.html.twig, вы всегда сможете
увидеть, какие опции у вас есть.
Tip
За кулисами, эти переменные доступны объекту вашей формы,
когда компонент вызывает и в каждом
“узле” вашего дерева формы. Чтобы увидеть, какие переменные “просмотра”
имеет конкретное поле, найдите исходный код поля формы (и его родительских
полей) и посмотрите на две вышеописанные функции.
Note
Если вы одномоментно отображаете форму целиком (или целую встроенную
формы), то аргумент будет применён только к самой форме,
но не к её дочерям. Другими словами, следующее не будет передать
атрибут класса “foo” всем дочерним полям формы:
1 2 |
{# **не** работает - переменные не рекурсивны #} {{ form_widget(form, { 'attr' {'class' 'foo'} }) }} |
Справочник переменных формы
Следующие переменные общие для всех типов полей. Некоторые типы полей могут
иметь даже больше переменных, а некоторые переменные здесь на самом деле
применяются только к конкретным типам.
Предполагая, что у вас в шаблоне есть переменная , и вы хотите сослаться
на переменные в поле , получение доступа к переменным проходит с использованием
публичного свойства объекта :
-
Twig
1 2 3 4
<label for="{{ form.name.vars.id }}" class="{{ form.name.vars.required ? 'required' '' }}"> {{ form.name.vars.label }} </label>
-
PHP
1 2 3 4
<label for="<?php echo $view'form'->get('name')->vars'id' ?>" class="<?php echo $view'form'->get('name')->vars'required' ? 'required' '' ?>"> <?php echo $view'form'->get('name')->vars'label' ?> </label>
Переменная | Использование |
---|---|
Текущий экземпляр . | |
HTML-атрибут для отображения. | |
Имя поля (например, ) — но не HTML-атрибута, которое является . |
|
HTML-атрибута для отображения. | |
Массив любых ошибок, присоединённый к этому конкретному полю (например, ). Заметьте, что вы не можете использовать , чтобы определить валидность формы, так как возвращаются только “глобальные” ошибки: некоторые индивидуальные поля могут иметь ошибки. Вместо этого используйте опцию . |
|
Возвращает или в зависимости от того, отправлена ли форма целиком | |
Возвращает или в зависимости от того, валидна ли форма целиком. | |
Значение, которое будет использовано при отображении (чаще всего HTML-атрибут ). | |
Если , добавляется к полю. | |
Если , атрибут добавляется к полю, чтобы активировать валидацию HTML5. Кроме того, к ярлыку добавляется класс . |
|
Строка ярлыка, которая будет отображена. | |
Если , отобразит . Применяется только к корневому элементу формы. |
|
Массив ключей-значений, который будет отображён как HTML-атрибуты поля. | |
Массив ключей-значений, который будет отображён как HTML-атрибуты ярлыка. | |
Является ли поле носителем группы дочерних полей (например, поля , которое насамом деле является группой чекбоксов. |
|
Массив всех имён родительских типов. | |
Домен переводов для этой формы. | |
Уникальный ключ, используемый для кеширования. | |
Нормализованные данные типа. | |
Метод текущей формы (POST, GET, и т.д.). | |
Действие текущей формы. |
Именованные аргументов
{% for i in range(low=1, high=10, step=2) %} {{ i }}, {% endfor %}
Использование именованных аргументов делает шаблоны более понятными:
{{ data|convert_encoding('UTF-8', 'iso-2022-jp') }} {# В сравнении с #} {{ data|convert_encoding(from='iso-2022-jp', to='UTF-8') }}
Также позволяют Вам пропускать некоторые аргументы,
для которых Вы не хотите менять значение по умолчанию:
{# Первый аргумент — формат даты, который задан в приложении глобально #} {{ "now"|date(null, "Europe/Paris") }} {# Или можно пропустить ``format``, но указать ``timezone`` #} {{ "now"|date(timezone="Europe/Paris") }}
Вы также можете использовать за один вызов оба варианта вывода аргументов,
однако это не рекомендуется, потому что это может привести к путанице:
{{ "now"|date('d/m/Y H:i', timezone="Europe/Paris") }}
Tip
У каждой функции и фильтра есть страница документации,
где перечислено какие названия аргументов поддерживаются.
Пространства имен шаблонов¶
Хотя большинство приложений хранят свои щаблоны в каталоге по умолчанию ,
вам может понадобиться хранить некоторые (или все) из них в других каталогах. Используйте
опцию , чтобы сконфигурирвать эти дополнительные каталоги. Каждый путь
определяется как пара , где — это каталог шаблона, а —
пространство имен Twig, что объясняется позже:
-
YAML
1 2 3 4 5 6 7 8
# config/packages/twig.yaml twig # ... paths # каталоги релятивны к корневому каталогу проекта (но вы также # можете использовать абсолютные каталоги) 'email/default/templates' ~ 'backend/templates' ~
-
XML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
<!-- config/packages/twig.xml --> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:twig="http://symfony.com/schema/dic/twig" xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd http://symfony.com/schema/dic/twig https://symfony.com/schema/dic/twig/twig-1.0.xsd"> <twig:config> <!-- ... --> <!-- каталоги релятивны к корневому каталогу проекта, но вы также можете использовать абсолютные каталоги --> <twig:path>email/default/templates</twig:path> <twig:path>backend/templates</twig:path> </twig:config> </container>
-
PHP
1 2 3 4 5 6 7 8 9 10 11
// config/packages/twig.php use Symfony\Config\TwigConfig; return static function (TwigConfig $twig) { // ... // каталоги релятивны к корневому каталогу проекта (но вы также // можете использовать абсолютные каталоги) $twig->path('email/default/templates', null); $twig->path('backend/templates', null); };
При отображении шаблона, Symfony вначале ищет его в каталогах , которые
не определяют пространство имен, а затем откатывается до каталога шаблонов по умолчанию
(обычно, ).
Twig решает эту проблему с помощью пространства имен, которые группируют несколько
шаблонов под одним логичным именем, не связанным с их реальным местоположением. Обновите
предыдущую конфигурацию, чтобы определить пространство имен для каждого каталога шаблонов:
-
YAML
1 2 3 4 5 6
# config/packages/twig.yaml twig # ... paths 'email/default/templates' 'email' 'backend/templates' 'admin'
-
XML
1 2 3 4 5 6 7 8 9 10 11 12 13 14
<!-- config/packages/twig.xml --> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:twig="http://symfony.com/schema/dic/twig" xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd http://symfony.com/schema/dic/twig https://symfony.com/schema/dic/twig/twig-1.0.xsd"> <twig:config> <!-- ... --> <twig:path namespace="email">email/default/templates</twig:path> <twig:path namespace="admin">backend/templates</twig:path> </twig:config> </container>
-
PHP
1 2 3 4 5 6 7 8 9
// config/packages/twig.php use Symfony\Config\TwigConfig; return static function (TwigConfig $twig) { // ... $twig->path('email/default/templates', 'email'); $twig->path('backend/templates', 'admin'); };
Note
Одно пространство имен Twig может ассоциироваться более, чем с одним каталогом шаблонов.
В таком случае, порядок, в котором добавляются пути, важен, так как Twig начнет искать
шаблоны с первого определенного пути.
Экранирование HTML
При генерации HTML в шаблоне всегда есть риск того, что переменные будут
содержать специальные символы, которые влияют на полученный HTML. Есть два
варианта решения: вручную отмечать переменные, которые нужно экранировать или
автоматически экранировать все по умолчанию.
По умолчанию в Twig автоматическое экранирование переменных включено.
Стратегию автоматического экранирования можно настроить с помощью
и по умолчанию — « html«.
Работа с ручным экранированием
Если ручное экранирование включено, ответственность за безопасность переменных
лежит на вас. Что экранировать? Любую переменную, которой вы не доверяете.
Экранирование осуществляется с помощью фильтра или :
{{ user.username|e }}
По умолчанию фильтр использует режим экранирования,
но в зависимости от ситуации вы можете использовать любые другие доступные
способы экранирования:
{{ user.username|e('js') }} {{ user.username|e('css') }} {{ user.username|e('url') }} {{ user.username|e('html_attr') }}
Работа с автоматическим экранированием
Вне зависимости от того включено экранирование или нет, вы можете добавить
экранирование для блока кода с помощью тега :
{% autoescape %} В этом блоке все будет автоматически экранировано (с помощью HTML режима) {% endautoescape %}
По умолчанию автоматическое экранирование использует режим .
Если есть переменные для экранирования в других режимах, необходимо добавить этот
режим:
{% autoescape 'js' %} В этом блоке все будет автоматически экранировано (с помощью JavaScript режима) {% endautoescape %}
Расширяем Twig под WordPress
Все же для полноценной работы не хватает хуков. Для того чтобы их добавить нужно в twig зарегистрировать необходимые функции.
В Twig_Controller создаем метод register_functions и вызываем его в конце конструктора:
public function register_functions() { $this->twig->addFunction( new TwigFunction( 'action', function ( $context ) { $args = func_get_args(); array_shift( $args ); $args[] = $context; call_user_func_array( 'do_action', $args ); }, array( 'needs_context' => true ) ) ); $this->twig->addFunction( new TwigFunction( 'filter', function ( $context ) { $args = func_get_args(); array_shift( $args ); $args[] = $context; echo call_user_func_array( 'apply_filters', $args ); }, array( 'needs_context' => true ) ) ); }
Узнайте больше¶
- How to Use PHP instead of Twig for Templates
- Как использовать для шаблонов PHP вместо Twig
- Как получить доступ к пользователю, запросу, сессии и др. в Twig через переменную
- Как сбросить информацию об отладке в шаблонах Twig
- Как встраивать контроллеры в шаблон
- Как экранировать вывод в шаблонах
- Как работать с разными форматами вывода в шаблонах
- How to Inject Variables Automatically into all Templates
- Как внедрять переменные во все шаблоны (т.е. глобальные переменные)
- How to Embed Asynchronous Content with hinclude.js
- Как встроить асинхронное содержание с помощью hinclude.js
- Как упорядочить ваши шаблоны Twig, используя наследование
- Как использовать и регистрировать пути Twig с пространством имён
- Как переопределять шаблоны из сторонних пакетов
- Как отобразить шаблон без пользовательского контроллера
- Как проверить синтаксис ваших шаблонов Twig
- How to Write a custom Twig Extension
- Как написать пользовательское расширение Twig
Если вы не можете установить Xdebug …
… читать дальше и удачи тебе, мой друг.
{{ dump() }}
{{ dump(variable_name) }}
Список доступных переменных (на верхнем уровне):
{{ dump(_context|keys) }}
Если у вас есть подмодуль Devel kint (для установки требуется require-dev с Composer с использованием composer require —dev drupal/devel 1.0-alpha1 и установка с Drush с помощью drush -y en kint), вы можете получить гармоничное отображение переменных, доступных для ветки с помощью :
{{ kint() }}
Существует очень хороший шанс, что kint заблокирует ваш браузер, когда рендеринг станет очень большим. В этом случае следующие модули могут работать лучше для вас:
https://www.drupal.org/project/vardumper
Или вы можете использовать модуль Vardumper Twig, который содержит Vardumper для twig. Вы можете получить гармоничное отображение переменных, доступных для twig:
{{ dump() }} {{ dump(variable_name) }}
{{ vardumper() }} {{ vardumper(variable_name) }}
https://www.drupal.org/project/twig_vardumper
… но также учтите, что потратить час или два на то, чтобы заставить работать Xdebug, ваша жизнь станет намного проще, так как для этого нужно знать, какие переменные вы можете использовать.
Экранирование вывода¶
Предтавьте, что ваш шаблон включает в себя код для отображения
имени пользователя. Если зловредный пользователь установит
в качестве своего имени, и вы выведете это значение без изменений, приложение отобразит
всплывающее окно JavaScript.
Это известно как атака (XSS). И хотя предыдущий пример
выглядит безобидным, нападчик может написать более продвинутый код JavaScript, чтобы
выполнить зловредные действия.
Чтобы предотвратить эту атаку, используйте “экранирование вывода”, чтобы
преобразовать символы, имеющие особое значение (например, замените на
HTML-сущность«<«). Приложения Symfony безопасны по умолчанию, так как они
выполняют автоматическое экранирование вывода благодаря
:
1 2 3 |
<p>Hello {{ name }}</p> {# если 'name' - '<script>alert('hello!')</script>', Twig выведет это: '<p>Hello <script>alert('hello!')</script></p>' #} |
Если вы отображаете переменную, которой можно доверять, и которая имеет HTML-содержание,
используйте фильтр Twig raw, чтобы отключить экранирование вывода для этой переменной:
1 2 3 |
<h1>{{ product.title|raw }}</h1> {# если 'product.title' - 'Lorem <strong>Ipsum</strong>', Twig выведет именно это вместо 'Lorem <strong>Ipsum</strong>' #} |