Ocorreu um problema em que um bloco que deveria ser único por página não é para usuários desconectados. O problema é um plug-in de bloco personalizado que tenho em uma página de pesquisa de visualizações que contém filtros personalizados (como uma substituição personalizada de filtros expostos. O bloco colocado por meio de / admin / structure / block).
Com base no que aprendi sobre o Drupal 8, adicionei os contextos de cache à minha matriz de compilação:
public function build() {
$search_form = \Drupal::formBuilder()->getForm('Drupal\mymodule\Form\SearchForm');
return [
'search_form' => $search_form,
'#cache' => ['contexts' => ['url.path', 'url.query_args']]
];
}
Mas parece que isso deve estar incorreto porque, quando desconectado, o bloco é armazenado em cache na primeira visualização e, quando o URL é alterado, ele não mostra uma nova versão do bloco.
Eu pensei que poderia ser a página de visualização que estava causando o problema, mas mesmo quando desativei o cache na página de visualização, o problema permaneceu.
Consegui corrigir o problema de várias maneiras, por exemplo, usando um gancho preprocess_block:
function mymodule_preprocess_block__mycustomsearchblock(&$variables) {
$variables['#cache']['contexts'][] = 'url.path';
$variables['#cache']['contexts'][] = 'url.query_args';
}
Mas me incomodou que eu não pudesse simplesmente colocar os contextos de cache na matriz de compilação do meu bloco.
Como meu bloco estende o BlockBase, decidi experimentar o método getCacheContexts (), especialmente porque vi que alguns módulos no núcleo estão fazendo dessa maneira.
public function getCacheContexts() {
return Cache::mergeContexts(parent::getCacheContexts(), ['url.path', 'url.query_args']);
}
Isso também corrigiu o problema, mas, curiosamente, quando eu mostro as variáveis na função de bloco de pré-processo, elas não são exibidas em $ variable ['# cache'] ['contexts'], mas são exibidas nos elementos $ variable [' '] [' # cache '] [' contextos ']
array:5 [▼
0 => "languages:language_interface"
1 => "theme"
2 => "url.path"
3 => "url.query_args"
4 => "user.permissions"
]
Estou tentando descobrir como isso funciona e por que não estava funcionando na função de compilação.
Olhando para /core/modules/block/src/BlockViewBuilder.php na função viewMultiple (), parece que ele extrai as tags de cache da entidade e do plug-in:
'contexts' => Cache::mergeContexts(
$entity->getCacheContexts(),
$plugin->getCacheContexts()
),
Então, isso explica por que adicionar um método getCacheContexts () ao meu plug-in de bloco adiciona os contextos ao meu bloco. Além disso, olhando para o método preRender na mesma classe, parece que ele não usa a matriz de cache na função de construção de blocos, o que me confunde, pois parece que a maneira de adicionar cache no Drupal 8 é adicionar um #cache elemento para renderizar elementos.
Então, minha pergunta é:
1) Os contextos de cache adicionados diretamente à matriz em um plug-in de bloco são ignorados?
2) Em caso afirmativo, existe uma maneira de contornar isso, precisamos adicioná-lo a um elemento filho da matriz de compilação?
3) Se o contexto adicionado diretamente for ignorado, a adição de um getCacheContexts () é o caminho a seguir para plug-ins de bloco em módulos personalizados?