Drupal preprocess hooks: Waarom de `url.path` cache context belangrijk is
Wanneer u de uitvoer in een preprocess-hook aanpast op basis van de huidige route of het huidige pad, moet u Drupal's render-cache ook vertellen wat die uitvoer varieert. Anders kan het eerste gerenderde resultaat worden gecached en overal worden hergebruikt.
De situatie
Beschouw een aangepaste preprocess voor het brandingblok dat een andere sitenaam toont op blog-nodes:
getRouteName();
// Controleer of we op een blogpagina zijn
if ($route_name === 'entity.node.canonical') {
$node = $route_match->getParameter('node');
if ($node && $node->bundle() === 'blog') {
// Op blogpagina's, pas de sitenaam aan om "HELLO WORLD" weer te geven
$variables['site_name'] = 'HELLO WORLD';
}
}
// Op de homepage en andere pagina's, behoud de oorspronkelijke sitenaam
}
Zonder de regel die de cachecontext toevoegt ($variables['#cache']['contexts'][] = 'url.path';
), kan Drupal de eerste versie die het rendert (bijvoorbeeld de blogversie) cachen en hergebruiken op elke pagina. Daarom zag u overal dezelfde tekst.
Waarom dit gebeurt
- Render cachen: Drupal cacht render-arrays voor prestaties.
- Variërende uitvoer: Als de uitvoer verandert per pad of route, moet de cache-sleutel die variabiliteit bevatten.
- Cache-contexten: Het toevoegen van
url.path
(of een specifiekere context) vertelt Drupal om aparte cache-variaties per pad te onderhouden.
Is dit waar voor alle preprocess-hooks?
Ja, de regel geldt voor elke renderbare uitvoer die varieert. Preprocess-hooks passen vaak render-arrays of templatevariabelen aan die deel gaan uitmaken van de render-cache. Als uw logica varieert op basis van:
- Pad of route â voeg
url.path
ofroute
toe - Huidige gebruiker â voeg
user
toe (of meer gedetailleerde contexten zoalsuser.roles
) - Taal â voeg
languages:language_interface
toe - Thema of breakpoint â voeg
theme
,responsive_image_style
, etc. toe
Preprocess zelf is niet speciaal; wat ertoe doet, is of de resulterende render-array anders gecached moet worden tussen verzoeken. Als de uitvoer varieert, declareer dan de juiste cache-contexten.
De juiste cache-context kiezen
- Geef de voorkeur aan precisie: Als u afhankelijk bent van de canonieke node, overweeg dan
route
in plaats vanurl.path
om onnodige cache-fragmentatie te voorkomen (bijv. query-strings of aliassen). - Op entiteiten gebaseerde blokken: Wanneer u afhankelijk bent van een entiteit (zoals een node), voeg dan cache-afhankelijkheden toe, zodat bewerkingen correct worden opgeschoond:
$variables['#cache']['tags'][] = 'node:' . $node->id();
- Max-age: Houd
max-age
op de standaardwaarde (permanent), tenzij de uitvoer echt verloopt.
Veiligere alternatief: Afleiden van de render-array
In plaats van globale variabelen te gebruiken, kunt u ook cacheerbare metadata toevoegen met CacheableMetadata
om contexten en tags veilig samen te voegen:
addCacheContexts(['route']);
$route_match = \Drupal::routeMatch();
if ($route_match->getRouteName() === 'entity.node.canonical') {
$node = $route_match->getParameter('node');
if ($node && $node->bundle() === 'blog') {
$variables['site_name'] = 'HELLO WORLD';
$cacheable->addCacheTags(['node:' . $node->id()]);
}
}
$cacheable->applyTo($variables);
}
Checklist
- Verandert de uitvoer per pad of route? Voeg
url.path
ofroute
toe. - Is er afhankelijkheid van een entiteit? Voeg cache-tags toe voor die entiteit.
- Varieert het per gebruiker of taal? Voeg de bijpassende contexten toe.
- Houd
max-age
hoog; vertrouw op tags voor ongeldigmaking.
Conclusie
Jaâals uw preprocess-logica de uitvoer per pagina verandert, moet u de bijbehorende cache-contexten declareren. Anders zal Drupal graag hetzelfde gecachte resultaat overal serveren.