Библиотеки: стили и скрипты
Файлы CSS и JavaScript в Drupal не подключают тегами в шаблоне. Их объединяют в библиотеку — именованный набор файлов, — а затем прикрепляют её к тому, что выводится. Drupal сам добавит теги на страницу, объединит и сожмёт файлы.
Файлы стилей
Создайте папку css в модуле и файл в ней:
/* web/modules/custom/blog/css/card.css */
.blog-card {
padding: 16px;
border: 1px solid #d0d7de;
border-radius: 8px;
}Сам по себе файл ещё никуда не подключён.
Описание библиотеки
Библиотеки модуля описывают в файле blog.libraries.yml в корне папки модуля. Создайте его вручную:
# web/modules/custom/blog/blog.libraries.yml
card:
css:
theme:
css/card.css: {}card — имя библиотеки. Полное имя состоит из имени модуля и имени библиотеки: blog/card. Пути к файлам пишут относительно папки модуля. Ключ theme — уровень стилей: он определяет порядок подключения, для оформления компонентов подходят component и theme.
Подключение в массиве вывода
// web/modules/custom/blog/src/Controller/BlogController.php
public function list(): array
{
return [
'#theme' => 'blog_card',
'#title' => 'Первая статья',
'#text' => 'Короткое описание статьи.',
'#attached' => ['library' => ['blog/card']],
];
}После drush cr карточка на странице /blog получит рамку и отступы. Файл загрузится только на тех страницах, где выведен этот элемент.
Подключение в шаблоне
То же самое можно сделать прямо в шаблоне Twig:
{# web/modules/custom/blog/templates/blog-card.html.twig #}
{{ attach_library('blog/card') }}
<article class="blog-card">
<h2>{{ title }}</h2>
<p>{{ text }}</p>
</article>Так удобнее: стили привязаны к шаблону и подключатся везде, где он используется.
Скрипты
Добавьте в библиотеку файл JavaScript и зависимости:
# web/modules/custom/blog/blog.libraries.yml
card:
css:
theme:
css/card.css: {}
js:
js/card.js: {}
dependencies:
- core/drupal
- core/onceЗависимости — другие библиотеки, которые должны загрузиться раньше. core/drupal даёт объект Drupal, core/once — функцию once.
// web/modules/custom/blog/js/card.js
(function (Drupal, once) {
Drupal.behaviors.blogCard = {
attach(context) {
once('blog-card', '.blog-card', context).forEach((card) => {
card.addEventListener('click', () => {
card.classList.toggle('is-open');
});
});
},
};
})(Drupal, once);Код оформлен как поведение. Drupal вызывает attach при загрузке страницы и каждый раз, когда на неё добавляется новая разметка. Функция once следит, чтобы обработчик навешивался на каждую карточку один раз. Щелчок по карточке теперь переключает класс is-open.
На всех страницах
Библиотеку, нужную везде, подключает хук в blog.module:
// web/modules/custom/blog/blog.module
/**
* Implements hook_page_attachments().
*/
function blog_page_attachments(array &$attachments): void
{
$attachments['#attached']['library'][] = 'blog/card';
}Частая ошибка
Вы изменили CSS, а страница выглядит по-старому. Причин обычно две. Первая — объединение файлов: на время разработки отключите его на странице «Конфигурация → Разработка → Производительность». Вторая — кеш: blog.libraries.yml читается только при drush cr. И не подключайте файлы тегами link и script в шаблоне: Drupal не узнает о них и не сможет ни объединить, ни загрузить зависимости.