Me he encontrado con un problema en el que un bloque que debería ser único por página no es para usuarios desconectados. El problema es un complemento de bloque personalizado que tengo en una página de búsqueda de vistas que contiene filtros personalizados (algo así como un reemplazo personalizado para filtros expuestos. El bloque se coloca a través de / admin / structure / block).
Según lo que aprendí sobre Drupal 8, agregué los contextos de caché a mi matriz de compilación:
public function build() {
$search_form = \Drupal::formBuilder()->getForm('Drupal\mymodule\Form\SearchForm');
return [
'search_form' => $search_form,
'#cache' => ['contexts' => ['url.path', 'url.query_args']]
];
}
Pero parece que esto debe ser incorrecto porque cuando se cierra la sesión, el bloque se almacena en caché en la primera vista, y cuando la URL cambia, no se muestra una nueva versión del bloque.
Pensé que podría ser la página de vista la que estaba causando el problema, pero incluso cuando desactivé el almacenamiento en caché en la página de vista, el problema persistió.
Pude solucionar el problema de varias maneras, por ejemplo, usando un gancho preprocess_block:
function mymodule_preprocess_block__mycustomsearchblock(&$variables) {
$variables['#cache']['contexts'][] = 'url.path';
$variables['#cache']['contexts'][] = 'url.query_args';
}
Pero me molestó que no pudiera simplemente poner los contextos de caché en la matriz de compilación de mi bloque.
Dado que mi bloque extiende BlockBase, decidí probar el método getCacheContexts (), especialmente porque vi que algunos módulos dentro del núcleo lo están haciendo de esta manera.
public function getCacheContexts() {
return Cache::mergeContexts(parent::getCacheContexts(), ['url.path', 'url.query_args']);
}
Esto también soluciona el problema, pero curiosamente, cuando imprimo las variables en la función de bloque de preproceso, estas no se muestran en $ variables ['# caché'] ['contextos'], pero sí se muestran en $ variables ['elementos '] [' # caché '] [' contextos ']
array:5 [▼
0 => "languages:language_interface"
1 => "theme"
2 => "url.path"
3 => "url.query_args"
4 => "user.permissions"
]
Estoy tratando de descubrir cómo funciona esto y por qué no funcionaba desde la función de compilación.
Al mirar /core/modules/block/src/BlockViewBuilder.php en la función viewMultiple (), parece que extrae las etiquetas de caché de la entidad y el complemento:
'contexts' => Cache::mergeContexts(
$entity->getCacheContexts(),
$plugin->getCacheContexts()
),
Eso explica por qué agregar un método getCacheContexts () a mi complemento de bloque agrega los contextos a mi bloque. Además, al observar el método preRender en la misma clase, parece que no usa la matriz de caché en la función de construcción de bloques, lo que me confunde, ya que parece que la forma de agregar el almacenamiento en caché en Drupal 8 es agregar un #caché elemento para representar elementos.
Entonces mi pregunta es,
1) ¿Se ignoran los contextos de caché agregados directamente en la matriz en un complemento de bloque?
2) Si es así, ¿hay alguna forma de evitarlo? ¿Necesitamos agregarlo a un elemento hijo de la matriz de compilación?
3) Si se ignora el contexto agregado directamente, ¿agregar el getCacheContexts () es el camino a seguir para los complementos de bloque en módulos personalizados?