←Terug naar het blog

Drupal preprocess hooks: Waarom de `url.path` cache context belangrijk is

2025-09-06‱8 minuten leestijd

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 of route toe
  • Huidige gebruiker → voeg user toe (of meer gedetailleerde contexten zoals user.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 van url.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 of route 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.