Темизация блока в зависимости от региона в котором он находится
Чем больше я развлекаюсь с Друпалом, тем чаще убеждаюсь, что в "работе из коробки" в этом движке работает только коробка. Шаг в лево или право требует допила, а казалось бы логичные хотелки - начертания пентаграммы и вызова демонов. Но тут, видимо, как в случае с ежиками, кактусами и девушками - бесит, но жутко интересно.
В адаптации легкой темы на Bootstrap 5 возникла задача изменить отображение формы поиска в определенном регионе - там и только там. Input формы должен был растягиваться на ширину страницы. Основная тема Bootstrap Barrio сделать это не прибегая к насилию не позволила.
Решение 1.
Модуль Twig Tweak
Расширение добавляет достаточно внушительный перечень фильтров и функций в шаблонизатор. Можно глянуть здесь
Вместо региона в файле page.html.twig вставляем
{{ drupal_form ('Drupal\\search\\Form\\SearchBlockForm') }}
и включаем магию css.
Штука несомненно крутая и я почти соблазнился. Способ прямого обращения к блоку или форме не всегда позволяет гибко настраивать вывод. И хотелось разобраться как все-таки мою задачу можно было бы решить через twig и условия if или for в самих шаблонах сущностей.
Решение 2.
Курение буржуйского интернета принесло такой хук (MYTHEME.theme):
use Drupal\block\Entity\Block;
function MYTHEME_theme_suggestions_block_alter(array &$suggestions, array $variables) {
if (!empty($variables['elements']['#id'])) {
$block = Block::load($variables['elements']['#id']);
$suggestions[] = 'block__' . $block->getRegion() . '__' . $variables['elements']['#id'];
}
/* Use this 'else if' only if you are using page_manager module and want to know which region is the block */
else if (isset($variables['elements']['#configuration']['region'])) {
$suggestions[] = 'block__page_' . $variables['elements']['#configuration']['region'] . '__' . end(explode(':', $variables['elements']['#plugin_id']));
}
return $suggestions;
}
Данный хук создает вариант использования шаблона блока для региона. Навример block--top-offcanvas--mytheme-search.html.twig который мы и темизирум на свое усмотрение.
На этом варианте уже можно было бы и остановиться, но поиск решения для twig же стал делом принципа и моего ОКР.
Решение 3.
Один из вариантов реализации хука я нашел на drupal.org, а с условием помогла дискорд-друпал-банда Никлана. Очень отзывчивые товарищи.
Итак, чтобы формировать условие внутри шаблонов сущностей, в нашем случае это block, нужно этим сущностям рассказать о наших планах. Ибо из коробки они наших хотелок не понимают: "Блок не знает в каком регионе он используется внутри."
Хук дает блоку понять, что он в регионе и записывает этот регион в строку
use Drupal\block\Entity\Block;
function MYTHEME_preprocess_block(&$vars) {
if (isset($vars['elements']['#id'])) {
$block_id = $vars['elements']['#id'];
$block = \Drupal\block\Entity\Block::load($block_id);
if ($block) {
$vars['region'] = $block->getRegion();
}
}
}
Теперь есть как минимум два варианта использования хука.
1. мы можем задать блоку класс если он помещен в регион:
в файл block.html.twig добавить
{%
set classes = [
'region-'~ region|clean_class,
]
%}
"region-машинное имя" нашего региона добавится в классы блока, типа
div class=region-top-offcanvas
тогда мы можем использовать стандартный синтаксис твиг, и задать условие через наличие класса в шаблоне блока
{% block content %}
{% if attributes.hasClass('region-top-offcanvas') %} //если в атрибутах есть класс то
2. Наконец таки, слава Никлану, добавить вожделенное условие в twig про конкретно регион. В моем случае оно выглядело так:
{% block content %}
{% if region == 'top_offcanvas' %}
<div{{ content_attributes.addClass('superclass') }}>
{{ parent() }}
{% else %}
<div{{ content_attributes.addClass('content', 'container-inline') }}>
{{ parent() }}
{% endif %}
{% endblock %}
Когда передо мной встала эта задача, то единственным адкватным решением я считал только самый последний вариант и о существовании всех остальных даже не подозревал. Да, друпал, сцуко неочевидный. Но очень интересный.
Информация
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.