Wystąpił problem polegający na tym, że blok, który powinien być unikalny na stronie, nie jest dla wylogowanych użytkowników. Problemem jest niestandardowa wtyczka blokowa, którą mam na stronie wyszukiwania widoków, która zawiera niestandardowe filtry (coś w rodzaju niestandardowego zamiennika dla odsłoniętych filtrów. Blok umieszczony przez / admin / structure / block).
Na podstawie tego, czego dowiedziałem się o Drupal 8, dodałem konteksty pamięci podręcznej do mojej tablicy kompilacji:
public function build() {
$search_form = \Drupal::formBuilder()->getForm('Drupal\mymodule\Form\SearchForm');
return [
'search_form' => $search_form,
'#cache' => ['contexts' => ['url.path', 'url.query_args']]
];
}
Wygląda jednak na to, że musi to być niepoprawne, ponieważ po wylogowaniu blok zostanie zapisany w pamięci podręcznej przy pierwszym widoku, a gdy zmieni się adres URL, nie będzie pokazywał nowej wersji bloku.
Myślałem, że przyczyną może być strona widoku, ale nawet po wyłączeniu buforowania na stronie widoku problem pozostał.
Byłem w stanie rozwiązać problem na kilka sposobów, na przykład za pomocą haka preprocess_block:
function mymodule_preprocess_block__mycustomsearchblock(&$variables) {
$variables['#cache']['contexts'][] = 'url.path';
$variables['#cache']['contexts'][] = 'url.query_args';
}
Ale przeszkadzało mi to, że nie mogłem po prostu umieścić kontekstów pamięci podręcznej w tablicy kompilacji mojego bloku.
Ponieważ mój blok rozszerza BlockBase, postanowiłem wypróbować metodę getCacheContexts (), zwłaszcza że widziałem, że niektóre moduły w rdzeniu robią to w ten sposób.
public function getCacheContexts() {
return Cache::mergeContexts(parent::getCacheContexts(), ['url.path', 'url.query_args']);
}
To również rozwiązało problem, ale co ciekawe, kiedy wypisuję zmienne w funkcji bloku przetwarzania wstępnego, nie są one wyświetlane w $ zmiennych ['# cache'] ['kontekstach'], ale pokazują się w elementach $ zmiennych [' '] [' # cache '] [' konteksty ']
array:5 [▼
0 => "languages:language_interface"
1 => "theme"
2 => "url.path"
3 => "url.query_args"
4 => "user.permissions"
]
Próbuję dowiedzieć się, jak to działa i dlaczego nie działa z funkcji kompilacji.
Patrząc na /core/modules/block/src/BlockViewBuilder.php w funkcji viewMultiple (), wygląda na to, że pobiera tagi pamięci podręcznej z encji i wtyczki:
'contexts' => Cache::mergeContexts(
$entity->getCacheContexts(),
$plugin->getCacheContexts()
),
To wyjaśnia, dlaczego dodanie metody getCacheContexts () do mojej wtyczki bloku dodaje konteksty do mojego bloku. Patrząc na metodę preRender w tej samej klasie, wygląda na to, że nie używa ona tablicy pamięci podręcznej w funkcji budowania bloków, co mnie dezorientuje, ponieważ wydaje się, że sposobem na dodanie buforowania w Drupal 8 jest dodanie pamięci podręcznej # element do renderowania elementów.
Więc moje pytanie brzmi:
1) Czy konteksty pamięci podręcznej dodawane bezpośrednio do tablicy w wtyczce bloku są ignorowane?
2) Jeśli tak, to czy można to obejść, czy musimy dodać go do elementu potomnego tablicy kompilacji?
3) Jeśli kontekst dodany bezpośrednio jest ignorowany, czy dodanie getCacheContexts () jest sposobem na wtyczki blokowe w niestandardowych modułach?