J'ai rencontré un problème où un bloc qui devrait être unique par page n'est pas destiné aux utilisateurs déconnectés. Le problème est un plugin de bloc personnalisé que j'ai sur une page de recherche de vues qui contient des filtres personnalisés (un peu comme un remplacement personnalisé pour les filtres exposés. Le bloc placé via / admin / structure / block).
Sur la base de ce que j'ai appris sur Drupal 8, j'ai ajouté les contextes de cache à mon tableau de build:
public function build() {
$search_form = \Drupal::formBuilder()->getForm('Drupal\mymodule\Form\SearchForm');
return [
'search_form' => $search_form,
'#cache' => ['contexts' => ['url.path', 'url.query_args']]
];
}
Mais il semble que cela doit être incorrect, car une fois déconnecté, le bloc serait mis en cache sur la première vue, et lorsque l'URL a changé, il n'affichait pas une nouvelle version du bloc.
Je pensais que c'était peut-être la page d'affichage qui causait le problème, mais même lorsque j'ai désactivé la mise en cache sur la page d'affichage, le problème est resté.
J'ai pu résoudre le problème de plusieurs manières, par exemple, en utilisant un hook preprocess_block:
function mymodule_preprocess_block__mycustomsearchblock(&$variables) {
$variables['#cache']['contexts'][] = 'url.path';
$variables['#cache']['contexts'][] = 'url.query_args';
}
Mais cela me dérangeait de ne pas pouvoir simplement mettre les contextes de cache dans le tableau de construction de mon bloc.
Étant donné que mon bloc étend BlockBase, j'ai décidé d'essayer la méthode getCacheContexts (), d'autant plus que j'ai vu certains modules dans le noyau le faire de cette façon.
public function getCacheContexts() {
return Cache::mergeContexts(parent::getCacheContexts(), ['url.path', 'url.query_args']);
}
Ce problème est également résolu, mais il est intéressant de noter que lorsque je génère les variables dans la fonction de bloc de prétraitement, celles-ci ne s'affichent pas dans $ variables ['# cache'] ['contextes'], mais elles apparaissent dans les éléments $ variables [' '] [' # cache '] [' contextes ']
array:5 [▼
0 => "languages:language_interface"
1 => "theme"
2 => "url.path"
3 => "url.query_args"
4 => "user.permissions"
]
J'essaie de comprendre comment cela fonctionne et pourquoi cela ne fonctionnait pas à partir de la fonction de génération.
En regardant /core/modules/block/src/BlockViewBuilder.php à la fonction viewMultiple (), il semble qu'il tire les balises de cache de l'entité et du plugin:
'contexts' => Cache::mergeContexts(
$entity->getCacheContexts(),
$plugin->getCacheContexts()
),
Cela explique donc pourquoi l'ajout d'une méthode getCacheContexts () à mon plugin de bloc ajoute les contextes à mon bloc. De plus, en regardant la méthode preRender dans la même classe, il semble qu'elle n'utilise pas le tableau de cache dans la fonction de construction de blocs, ce qui m'embrouille, car il semble que le moyen d'ajouter la mise en cache dans Drupal 8 est d'ajouter un #cache élément pour rendre les éléments.
Donc ma question est,
1) Les contextes de cache ajoutés directement sur la baie dans un plugin de bloc sont-ils ignorés?
2) Si oui, existe-t-il un moyen de contourner cela, devons-nous l'ajouter à un élément enfant du tableau de génération?
3) Si le contexte ajouté directement est ignoré, l'ajout d'un getCacheContexts () est-il la voie à suivre pour les plugins de bloc dans les modules personnalisés?