Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Библиотеки: стили и скрипты

Файлы 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 не узнает о них и не сможет ни объединить, ни загрузить зависимости.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.