В Drupal 8 немного усложнился процесс подключения своих стилей и скриптов. Теперь все js и css файлы должны быть объединены в так называемые libraries (библиотеки), описаны в файле *.libraries.yml
и подключены одним из нескольких способов. Начнём по порядку.
Создание файла *.libraries.yml
В файле *.libraries.yml
содержится описание всех библиотек модуля или темы, а так же зависимости этих библиотек.
Библиотека (library) это набор js и css файлов, выполняющих определённую функцию. Примеры встроенных в drupal библиотек — core/jquery
, core/jquery.ui.dialog
, ckeditor/drupal.ckeditor
. Библиотека может состоять всего из одного js или css файла и не иметь никаких зависимостей. Подключать отдельные файлы минуя их описание в *.libraries.yml
нельзя.
Пример файла *.libraries.yml
с описанием библиотеки jquery.ui.dialog
:
jquery.ui.dialog:
js:
jquery.ui.dialog.js: {}
css:
theme:
jquery.ui.dialog.css: {}
dependencies:
- core/jquery.ui
Как понятно из описания, библиотека jquery.ui.dialog
содержит один js файл jquery.ui.dialog.js
, один css файл jquery.ui.dialog.css
и зависит от другой библиотеки core/jquery.ui
, которая подключится автоматически.
Если какие-то стили нужно подключать на каждой странице и их никак не сгруппировать в отдельную библиотеку, то можно описать их под именем global-styling
(актуально для тем):
global-styling:
css:
theme:
css/layout.css: {}
css/style.css: {}
css/colors.css: {}
Так же в *.libraries.yml
можно указать дополнительные параметры, такие как версия библиотеки, место подключения (шапка/подвал), порядок подключения и т.д. Пример:
mylibrary:
version: 1.0
header: true
js:
mylibrary-min.js: { minified: true }
mylibrary-second.js { preprocess: false, attributes: { async: true } }
css:
theme:
https://example.com/externalcss.css: { type: external }
mylibrary.css: { weight: 1 }
mylibrary-print.css: { media: print }
Подробнее в документации.
Подключение библиотек
В своей теме
Чтобы добавить библиотеку на все страницы сайта, нужно в файле темы *.info.yml
прописать параметр libraries
с именем библиотеки в формате extension_name/library_name
:
libraries:
- mytheme/global-styling
- mytheme/mylibrary
Чтобы добавить библиотеку только на определённую страницу/страницы, можно воспользоваться препроцессом:
/**
* Preprocess function for page.twig.html.
*/
function THEMENAME_preprocess_page(array &$vars): void {
if ($vars['is_front']) {
$vars['#attached']['library'][] = 'core/drupal.ajax';
}
}
Как видно, подключать библиотеки можно простым добавлением в любой рендер-массив параметра #attached
. Отдельной функции для подключения, как это было в Drupal 7, больше нет.
Так же подключать библиотеки можно прямо из *.html.twig
файла с помощью функции attach_library()
:
{{ attach_library('modulename/libraryname') }}
<div>Some markup {{ message }}</div>
В своём модуле
Для модулей есть отдельный хук hook_page_attachments()
:
/**
* Implements hook_page_attachments().
*/
function MODULENAME_page_attachments(array &$page): void {
$page['#attached']['library'][] = 'modulename/libraryname';
}
Хотя способ с препроцессом и twig функцией тоже будет работать.
Изменение файлов библиотек
Модули и темы могут добавлять/подменять/удалять файлы чужих библиотек.
Темы это могут сделать из своего *.info.yml
файла:
libraries-override:
modulename/libraryname:
js:
# Подмена файла библиотеки
filename.js: myfilename.js
# Удаление файла библиотеки
filename.js: false
# Добавление зависимости к чужой библиотеке
libraries-extend:
modulename/libraryname:
- mytheme/mylibrary
Модулям доступен вариант с хуком hook_library_info_alter()
:
/**
* Implements hook_library_info_alter().
*/
function MODULENAME_library_info_alter(array &$libraries, string $extension): void {
if ($extension == 'other_modulename') {
// Удаление файла библиотеки
unset($libraries['libraryname']['js']['filename.js']);
// Добавление файла в библиотеку
$filepath = '/' . drupal_get_path('module', 'modulename') . '/filename.js';
$libraries['libraryname']['js'][$filepath] = [];
// Подмена файла библиотеки
unset($libraries['libraryname']['js']['filename.js']);
$filepath = '/' . drupal_get_path('module', 'modulename') . '/myfilename.js';
$libraries['libraryname']['js'][$filepath] = [];
// Добавление зависимости
$libraries['libraryname']['dependencies'][] = 'modulename/libraryname';
}
}
Полезные ссылки:
— Adding stylesheets (CSS) and JavaScript (JS) to a Drupal 8 theme
— Adding stylesheets (CSS) and JavaScript (JS) to a Drupal 8 module
— CSS file organization (for Drupal 8)
— Drupal 8: Libraries API (Добавление CSS/JS на страницы)
— Централизованный способ отключить в рантайме определённую библиотеку
- Показать процесс загрузки ajax таба в Quicktabs 7.x-3.x
- Два видеокурса по темизации Drupal 7 от Drupalize.me (бывшие Lullabot)
- Добавляем CSS классы в body на основе текущего пути
- Модуль Code per Node — индивидуальный css и javascript код для нод
- Создание сравнительной таблицы с значениями из EAV Field
Комментарии
а еще переменная $ в коде jQuery в друпале не работает просто так, нужно параметр jQuery передавать в самовызываемую функцию, а еще не все подключаемые библиотеки срабатывают как надо.. а еще бывает нужно jQuery подключать различные версии, вообщем короче такой гемор(((
Привет!
Как указано в статье,
{{ attach_library('modulename/libraryname') }}
подключает библиотеку в нужном месте .html.twig, а если я хочу подключить библиотеку js с атрибутом defer -
<script src="js/scripts.js" defer></script>
, то как это сделать через attach?libraries.yml
Спасибо! А можно как-то подключить js только для залогинённых пользователей?
Добавить комментарий