Zurück zum Blog

Drupal Preprocess-Hooks: Warum der `url.path`-Cache-Kontext wichtig ist

2025-09-068 min read

Wenn Sie die Ausgabe in einem Preprocess-Hook basierend auf der aktuellen Route oder dem Pfad ändern, müssen Sie dem Render-Cache von Drupal auch mitteilen, was diese Ausgabe variiert. Andernfalls kann das erste gerenderte Ergebnis zwischengespeichert und überall wiederverwendet werden.

Die Situation

Betrachten Sie ein benutzerdefiniertes Preprocess für den Branding-Block, der auf Blog-Nodes einen anderen Seitennamen anzeigt:

getRouteName();

  // Prüfen, ob wir uns auf einer Blog-Seite befinden
  if ($route_name === 'entity.node.canonical') {
    $node = $route_match->getParameter('node');
    if ($node && $node->bundle() === 'blog') {
      // Auf Blog-Seiten den Seitennamen zu "HELLO WORLD" ändern
      $variables['site_name'] = 'HELLO WORLD';
    }
  }
  // Auf der Startseite und anderen Seiten den ursprünglichen Seitennamen beibehalten
}

Ohne die Zeile, die den Cache-Kontext hinzufügt ($variables['#cache']['contexts'][] = 'url.path';), kann Drupal die erste gerenderte Version (z. B. die Blog-Version) zwischenspeichern und auf jeder Seite wiederverwenden. Deshalb sahen Sie überall denselben Text.

Warum passiert das?

  • Render-Caching: Drupal speichert Render-Arrays zur Leistungssteigerung zwischen.
  • Variierende Ausgabe: Wenn sich die Ausgabe nach Pfad oder Route ändert, muss der Cache-Schlüssel diese Variabilität enthalten.
  • Cache-Kontexte: Das Hinzufügen von url.path (oder einem spezifischeren Kontext) teilt Drupal mit, separate Cache-Variationen pro Pfad beizubehalten.

Gilt das für alle Preprocess-Hooks?

Ja, die Regel gilt für jede renderbare Ausgabe, die variiert. Preprocess-Hooks modifizieren oft Render-Arrays oder Template-Variablen, die Teil des Render-Caches werden. Wenn Ihre Logik variiert nach:

  • Pfad oder Route → url.path oder route hinzufügen
  • Aktueller Benutzer → user (oder granularere Kontexte wie user.roles) hinzufügen
  • Sprache → languages:language_interface hinzufügen
  • Theme oder Breakpoint → theme, responsive_image_style usw. hinzufügen

Preprocess selbst ist nichts Besonderes; entscheidend ist, ob das resultierende Render-Array zwischen verschiedenen Anfragen unterschiedlich zwischengespeichert werden sollte. Wenn die Ausgabe variiert, deklarieren Sie die richtigen Cache-Kontexte.

Auswahl des richtigen Cache-Kontexts

  • Präzision bevorzugen: Wenn Sie von einem kanonischen Node abhängen, ziehen Sie route anstelle von url.path in Betracht, um unnötige Cache-Fragmentierung zu vermeiden (z. B. Query-Strings oder Aliase).
  • Entitätsbasierte Blöcke: Wenn Sie von einer Entität (wie einem Node) abhängen, fügen Sie Cache-Abhängigkeiten hinzu, damit Bearbeitungen korrekt bereinigt werden: $variables['#cache']['tags'][] = 'node:' . $node->id();
  • Max-age: Behalten Sie max-age auf dem Standardwert (permanent), es sei denn, die Ausgabe läuft wirklich ab.

Sicherere Alternative: Ableiten vom Render-Array

Anstatt Globals zu verwenden, können Sie auch Cacheability-Metadaten mit CacheableMetadata anhängen, um Kontexte und Tags sicher zusammenzuführen:

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);
}

Checkliste

  • Ändert sich die Ausgabe je nach Pfad oder Route? Fügen Sie url.path oder route hinzu.
  • Hängt sie von einer Entität ab? Fügen Sie Cache-Tags für diese Entität hinzu.
  • Variiert sie je nach Benutzer oder Sprache? Fügen Sie die passenden Kontexte hinzu.
  • Halten Sie max-age hoch; verlassen Sie sich für die Invalidierung auf Tags.

Fazit

Ja – wenn Ihre Preprocess-Logik die Ausgabe pro Seite ändert, müssen Sie die entsprechenden Cache-Kontexte deklarieren. Andernfalls liefert Drupal gerne dasselbe zwischengespeicherte Ergebnis überall aus.

Bleiben Sie auf dem Laufenden

Erhalten Sie die neuesten Beiträge und Einblicke in Ihren Posteingang.

Unsubscribe anytime. No spam, ever.