Ich bin auf ein Problem gestoßen, bei dem ein Block, der pro Seite eindeutig sein sollte, nicht für abgemeldete Benutzer geeignet ist. Das Problem ist ein benutzerdefiniertes Block-Plugin, das ich auf einer Ansichtssuchseite habe und das benutzerdefinierte Filter enthält (ähnlich wie ein benutzerdefinierter Ersatz für exponierte Filter. Der Block wird durch / admin / structure / block platziert).
Basierend auf dem, was ich über Drupal 8 gelernt habe, habe ich die Cache-Kontexte zu meinem Build-Array hinzugefügt:
public function build() {
$search_form = \Drupal::formBuilder()->getForm('Drupal\mymodule\Form\SearchForm');
return [
'search_form' => $search_form,
'#cache' => ['contexts' => ['url.path', 'url.query_args']]
];
}
Dies muss jedoch falsch sein, da der Block beim Abmelden bei der ersten Ansicht zwischengespeichert wird und bei Änderung der URL keine neue Version des Blocks angezeigt wird.
Ich dachte, es könnte die Ansichtsseite sein, die das Problem verursacht hat, aber selbst als ich das Caching auf der Ansichtsseite deaktivierte, blieb das Problem bestehen.
Ich konnte das Problem auf verschiedene Arten beheben, beispielsweise mithilfe eines preprocess_block-Hooks:
function mymodule_preprocess_block__mycustomsearchblock(&$variables) {
$variables['#cache']['contexts'][] = 'url.path';
$variables['#cache']['contexts'][] = 'url.query_args';
}
Aber es störte mich, dass ich die Cache-Kontexte nicht einfach in das Build-Array meines Blocks einfügen konnte.
Da mein Block BlockBase erweitert, habe ich beschlossen, die Methode getCacheContexts () auszuprobieren, insbesondere weil ich gesehen habe, dass einige Module im Kern dies auf diese Weise tun.
public function getCacheContexts() {
return Cache::mergeContexts(parent::getCacheContexts(), ['url.path', 'url.query_args']);
}
Dies hat auch das Problem behoben, aber interessanterweise werden diese, wenn ich die Variablen in der Vorverarbeitungsblockfunktion ausgeben, nicht in $ variables ['# cache'] ['context'] angezeigt, sondern in $ variables ['Elementen '] [' # cache '] [' context ']
array:5 [▼
0 => "languages:language_interface"
1 => "theme"
2 => "url.path"
3 => "url.query_args"
4 => "user.permissions"
]
Ich versuche herauszufinden, wie dies funktioniert und warum es mit der Build-Funktion nicht funktioniert hat.
Wenn Sie sich /core/modules/block/src/BlockViewBuilder.php in der Funktion viewMultiple () ansehen, sieht es so aus, als würden die Cache-Tags aus der Entität und dem Plugin abgerufen:
'contexts' => Cache::mergeContexts(
$entity->getCacheContexts(),
$plugin->getCacheContexts()
),
Das erklärt, warum das Hinzufügen einer getCacheContexts () -Methode zu meinem Block-Plugin die Kontexte zu meinem Block hinzufügt. Wenn man sich die preRender-Methode in derselben Klasse ansieht, sieht es so aus, als würde das Cache-Array in der Blockerstellungsfunktion nicht verwendet, was mich verwirrt, da das Hinzufügen von Caching in Drupal 8 anscheinend darin besteht, einen #cache hinzuzufügen Element zum Rendern von Elementen.
Meine Frage ist also:
1) Werden Cache-Kontexte, die direkt zum Array in einem Block-Plugin hinzugefügt wurden, ignoriert?
2) Wenn ja, gibt es einen Weg, dies zu umgehen, müssen wir es einem untergeordneten Element des Build-Arrays hinzufügen?
3) Wenn der direkt hinzugefügte Kontext ignoriert wird, ist das Hinzufügen von getCacheContexts () der richtige Weg, um Block-Plugins in benutzerdefinierten Modulen zu verwenden?