Ho riscontrato un problema in cui un blocco che dovrebbe essere univoco per pagina non è destinato agli utenti disconnessi. Il problema è un plug-in di blocco personalizzato che ho su una pagina di ricerca delle viste che contiene filtri personalizzati (una specie di rimpiazzo personalizzato per i filtri esposti. Il blocco inserito attraverso / admin / struttura / blocco).
Sulla base di ciò che ho imparato su Drupal 8, ho aggiunto i contesti di cache al mio array di 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']]
];
}
Ma sembra che questo non sia corretto perché quando disconnesso, il blocco verrebbe memorizzato nella prima vista e, quando l'URL cambiava, non mostrava una nuova versione del blocco.
Ho pensato che potesse essere la pagina di visualizzazione a causare il problema, ma anche quando ho disattivato la memorizzazione nella cache nella pagina di visualizzazione, il problema è rimasto.
Sono stato in grado di risolvere il problema in diversi modi, ad esempio utilizzando un hook preprocess_block:
function mymodule_preprocess_block__mycustomsearchblock(&$variables) {
$variables['#cache']['contexts'][] = 'url.path';
$variables['#cache']['contexts'][] = 'url.query_args';
}
Ma mi dava fastidio non poter semplicemente inserire i contesti della cache nell'array di build del mio blocco.
Poiché il mio blocco estende BlockBase, ho deciso di provare il metodo getCacheContexts (), soprattutto perché ho visto che alcuni moduli all'interno di core lo stanno facendo in questo modo.
public function getCacheContexts() {
return Cache::mergeContexts(parent::getCacheContexts(), ['url.path', 'url.query_args']);
}
Questo risolve anche il problema, ma è interessante notare che quando eseguo l'output delle variabili nella funzione del blocco di preelaborazione, queste non vengono visualizzate in $ variabili ['# cache'] ['contesti'], ma mostrano in $ variabili ['elementi '] [' # di cache '] [' contesti]
array:5 [▼
0 => "languages:language_interface"
1 => "theme"
2 => "url.path"
3 => "url.query_args"
4 => "user.permissions"
]
Sto cercando di capire come funziona e perché non funziona dalla funzione build.
Guardando /core/modules/block/src/BlockViewBuilder.php nella funzione viewMultiple (), sembra che tira i tag cache dall'entità e dal plugin:
'contexts' => Cache::mergeContexts(
$entity->getCacheContexts(),
$plugin->getCacheContexts()
),
Questo spiega perché l'aggiunta di un metodo getCacheContexts () al mio plug-in di blocco aggiunge i contesti al mio blocco. Inoltre, guardando il metodo preRender nella stessa classe, sembra che non usi l'array cache nella funzione build di blocchi, il che mi confonde, poiché sembra che il modo per aggiungere la cache in Drupal 8 sia aggiungere un #cache elemento per il rendering di elementi.
Quindi la mia domanda è
1) I contesti cache aggiunti direttamente sull'array in un plug-in di blocco vengono ignorati?
2) In tal caso, c'è un modo per aggirare questo, dobbiamo aggiungerlo a un elemento figlio dell'array build?
3) Se il contesto aggiunto direttamente viene ignorato, l'aggiunta di getCacheContexts () è la strada da percorrere per i plug-in di blocco nei moduli personalizzati?