Темы и переопределение шаблонов
Тема отвечает за внешний вид сайта: разметку страниц, стили и области для блоков. Модуль решает, что вывести, а тема — как это выглядит. Свою тему создают, чтобы изменять шаблоны ядра и чужих модулей, не трогая их файлы.
Где лежит тема
Свои темы лежат в web/themes/custom. Заготовку создаёт сценарий из ядра. Запустите его из папки web:
cd web
php core/scripts/drupal generate-theme blog_theme --path themes/custom
cd ..Появится папка web/themes/custom/blog_theme — копия стартовой темы ядра с готовыми шаблонами и стилями.
Включение
vendor/bin/drush theme:install blog_theme
vendor/bin/drush config:set system.theme default blog_theme -yПервая команда включает тему, вторая делает её основной. То же самое делается в панели, в разделе «Оформление». После этого сайт выглядит просто, почти без стилей — это ожидаемо для заготовки.
Что внутри
| Файл или папка | Для чего |
|---|---|
blog_theme.info.yml | Описание темы: название, базовая тема, области, библиотеки |
blog_theme.libraries.yml | Стили и скрипты темы |
blog_theme.theme | Функции PHP: подготовка переменных для шаблонов |
templates/ | Шаблоны Twig |
css/, js/ | Файлы стилей и скриптов |
В blog_theme.info.yml у темы type: theme, а ключ base theme называет тему, от которой наследуются шаблоны. Ключ regions перечисляет области, в которые размещают блоки.
Переопределение шаблона
Чтобы изменить разметку, в папку templates темы кладут файл с тем же именем, что у исходного шаблона. Материал выводится шаблоном node.html.twig. Сделаем отдельный шаблон только для статей:
{# web/themes/custom/blog_theme/templates/content/node--article.html.twig #}
<article{{ attributes.addClass('article') }}>
<h2><a href="{{ url }}">{{ label }}</a></h2>
<div class="article__body">
{{ content }}
</div>
</article>После drush cr статьи выводятся этой разметкой, а остальные типы материалов — прежней. label — заголовок, url — адрес материала, content — его поля, attributes — атрибуты тега, которые собрали Drupal и модули.
Варианты имён
Drupal перебирает имена шаблонов от самого точного к общему и берёт первый найденный файл.
| Файл | Когда применяется |
|---|---|
node--5.html.twig | Только материал с номером 5 |
node--article--teaser.html.twig | Статья в кратком виде |
node--article.html.twig | Любая статья |
node.html.twig | Любой материал |
page--front.html.twig | Каркас главной страницы |
block--system-branding-block.html.twig | Блок с логотипом |
Какие имена подходят для конкретного места страницы, подсказывает режим разработки Twig из урока об установке: в исходном коде страницы появляются комментарии со списком вариантов и путём к использованному файлу.
Так же переопределяют шаблон своего модуля: файл blog-card.html.twig в папке templates темы заменит шаблон из модуля blog.
Подготовка переменных
Новую переменную для шаблона добавляет функция в файле blog_theme.theme:
// web/themes/custom/blog_theme/blog_theme.theme
/**
* Implements hook_preprocess_node().
*/
function blog_theme_preprocess_node(array &$variables): void
{
$node = $variables['node'];
$variables['created_date'] = date('d.m.Y', $node->getCreatedTime());
}В шаблоне материала появится переменная: {{ created_date }} выведет дату создания. Имя функции складывается из имени темы, слова preprocess и имени шаблона.
Частая ошибка
Новый файл шаблона Drupal замечает только после drush cr: список шаблонов хранится в кеше. Изменения внутри уже найденного файла видны сразу, если включён режим разработки Twig. И проверьте имя: в файлах используются дефисы, двойной дефис отделяет уточнение — node--article.html.twig, а не node_article.html.twig.