Я столкнулся с проблемой, когда блок, который должен быть уникальным для каждой страницы, не предназначен для пользователей, вышедших из системы. Проблема заключается в том, что у меня есть плагин для пользовательских блоков на странице поиска представлений, который содержит пользовательские фильтры (что-то вроде пользовательской замены для открытых фильтров. Блок помещается через / admin / structure / block).
Основываясь на том, что я узнал о Drupal 8, я добавил контексты кеша в свой массив сборки:
public function build() {
$search_form = \Drupal::formBuilder()->getForm('Drupal\mymodule\Form\SearchForm');
return [
'search_form' => $search_form,
'#cache' => ['contexts' => ['url.path', 'url.query_args']]
];
}
Но, похоже, это должно быть неверно, потому что при выходе из системы блок кэшируется при первом просмотре, а при изменении URL-адреса не отображается новая версия блока.
Я думал, что это может быть проблема с страницей просмотра, но даже когда я отключил кэширование на странице просмотра, проблема осталась.
Мне удалось решить эту проблему несколькими способами, например, с помощью ловушки preprocess_block:
function mymodule_preprocess_block__mycustomsearchblock(&$variables) {
$variables['#cache']['contexts'][] = 'url.path';
$variables['#cache']['contexts'][] = 'url.query_args';
}
Но это беспокоило меня, я не мог просто поместить контексты кэша в массив сборки моего блока.
Поскольку мой блок расширяет BlockBase, я решил попробовать метод getCacheContexts (), тем более что я видел, что некоторые модули в ядре делают это именно так.
public function getCacheContexts() {
return Cache::mergeContexts(parent::getCacheContexts(), ['url.path', 'url.query_args']);
}
Это также исправило проблему, но, что интересно, когда я выводил переменные в функции блока предварительной обработки, они не отображаются в $ variable ['# cache'] ['contexts'], но они отображаются в $ variable ['elements '] [' # кэшировать '] [' контексты]
array:5 [▼
0 => "languages:language_interface"
1 => "theme"
2 => "url.path"
3 => "url.query_args"
4 => "user.permissions"
]
Я пытаюсь выяснить, как это работает, и почему это не работает из функции сборки.
Глядя на /core/modules/block/src/BlockViewBuilder.php функцию viewMultiple (), похоже, что она извлекает теги кеша из сущности и плагина:
'contexts' => Cache::mergeContexts(
$entity->getCacheContexts(),
$plugin->getCacheContexts()
),
Это объясняет, почему добавление метода getCacheContexts () в мой плагин блока добавляет контексты в мой блок. Также, глядя на метод preRender в том же классе, похоже, что он не использует массив кеша в функции сборки блоков, что меня смущает, так как кажется, что способ добавить кеширование в Drupal 8 - это добавить #cache элемент для отображения элементов.
Итак, мой вопрос,
1) Игнорируются ли контексты кеша, добавленные непосредственно в массив в блочном плагине?
2) Если так, есть ли способ обойти это, нужно ли добавить его в дочерний элемент массива сборки?
3) Если контекст, добавленный напрямую, игнорируется, является ли добавление getCacheContexts () способом пойти на блочные плагины в пользовательских модулях?