Шаблоны Twig и hook_theme
Шаблон — файл с разметкой, в которую подставляются данные. В Drupal шаблоны пишут на языке Twig. Свой шаблон нужен, когда готовых элементов вроде списка и таблицы мало и требуется собственная разметка — например, карточка статьи.
Чтобы шаблон заработал, нужны три шага: объявить его, создать файл и использовать в массиве вывода.
Шаг 1. Объявление
Шаблоны объявляет функция blog_theme() в файле blog.module. Этот файл лежит в корне папки модуля и содержит функции-хуки — о них отдельный урок. Создайте его вручную:
// web/modules/custom/blog/blog.module
/**
* Implements hook_theme().
*/
function blog_theme(): array
{
return [
'blog_card' => [
'variables' => ['title' => '', 'text' => '', 'tags' => []],
],
];
}В настоящем файле первой строкой идёт <?php. Функция объявляет шаблон blog_card с тремя переменными и значениями по умолчанию для них.
Шаг 2. Файл шаблона
Шаблоны модуля лежат в папке templates. Имя файла — имя шаблона, где подчёркивания заменены дефисами, с окончанием .html.twig:
{# web/modules/custom/blog/templates/blog-card.html.twig #}
<article class="blog-card">
<h2>{{ title }}</h2>
<p>{{ text }}</p>
</article>Двойные фигурные скобки выводят значение переменной. Оно экранируется автоматически: теги в тексте превратятся в безопасные символы.
Шаг 3. Использование
// web/modules/custom/blog/src/Controller/BlogController.php
public function list(): array
{
return [
'#theme' => 'blog_card',
'#title' => 'Первая статья',
'#text' => 'Короткое описание статьи.',
];
}Имя шаблона указывают в #theme, а переменные — свойствами с решёткой. После drush cr страница /blog покажет карточку с заголовком и абзацем.
Условия и циклы
Команды Twig пишут в скобках с процентом. Добавим в карточку список меток:
{# web/modules/custom/blog/templates/blog-card.html.twig #}
<article class="blog-card">
<h2>{{ title }}</h2>
<p>{{ text }}</p>
{% if tags %}
<ul>
{% for tag in tags %}
<li>{{ tag }}</li>
{% endfor %}
</ul>
{% endif %}
</article>Если передать '#tags' => ['PHP', 'Drupal'], под текстом появится список из двух пунктов. Без меток блок ul не выводится вовсе.
Что есть в Twig
| Запись | Что делает |
|---|---|
{{ title }} | Выводит переменную |
{{ node.label }} | Обращается к свойству или методу объекта |
{% if … %} … {% endif %} | Условие |
{% for item in items %} … {% endfor %} | Цикл |
{{ path('blog.list') }} | Адрес по имени маршрута |
{{ title|upper }} | Фильтр: преобразует значение |
{# текст #} | Комментарий |
Массив вывода в переменной выводится так же: {{ content }}. Drupal сам превратит его в разметку.
Частая ошибка
Шаблон не подхватывается, если имена не согласованы. В blog_theme() и в #theme пишут blog_card с подчёркиванием, а файл называется blog-card.html.twig — с дефисом. Переменные передаются как #title, а в variables объявлены как title: необъявленная переменная в шаблон не попадёт. После добавления шаблона обязательно выполните drush cr.