Dies funktioniert auf Basis von Entitäten und den dazugehörigen View Modes. Das Modul sieht vor, dass nicht von außen, sondern direkt an der Schnittstelle zur Ausgabe gecacht wird.

Zur besseren Vorstellung, worum es geht, ein kurzes Frage-Antwort-Spielchen.

Muss eine Entität wirklich bei jedem Seitenaufruf neu gerendert werden?

Nein, dass kann ja zum Beispiel mit Panels gecacht werden. Da kann eingestellt werden, wie lange der Inhalt eines Panes gecacht wird.

Das ist ja toll, aber wenn sich jetzt etwas an der Entität ändert? Zum Beispiel ein neues Bild?

Dann muss halt so lange gewartet werden, bis die oben eingestellte Zeit abgelaufen ist und sich der Cache neu aufbaut.

Und wie ist das bei Views?

Genau so. Wenn eine View gecacht wurde muss die Cache-Zeit abgewartet werden, bis neue Ergebnisse angezeigt werden. Zwar wird in dieser Zeit der Views-Query auch nicht ausgeführt, doch was nützt das auf einer Seite, welche aus Gründen zeit-aktuell sein muss?

Aber es gibt da doch andere Möglichkeiten, wie Varnish.

Ja, aber der Varnish spielt das Spiel nur so lange, wie sich niemand an der Seite anmeldet. In dem Moment wo Session-Cookies erstellt werden, gibt es auch mit dem Varnish Probleme.

Wir haben also mit den gewohnten Caching-Mechanismen in bestimmten Situation so unsere Schwierigkeiten.

Daher nun folgender Vorschlag

  1. Eine gerenderte Entität wird in einem bestimmten View Mode benötigt.
  2. Sie wird über eine Wrapper-Funktion angefragt.
  3. Hier wird sie geladen, zum render vorbereitet, gerendert, gecacht und zurück gegeben.
  4. Das nächste mal, wenn die selbe Entitität im selben View Mode benötigt wird, wird anstatt des Renderns das gecachte HTML zurück gegeben.
  5. Immer wenn sich eine Entität auf irgendeine Weise ändert, werden die Display Caches dieser Entität gelöscht. (Ach - daher der Name...)
  6. Wiederhole Schritt eins.

Oder anders: Die Entität verwaltet ihre Cache-Einträge selbst. Sie "weiß", wann sich ihre eigenen Inhalte ändern. Im Gegensatz zu den anzeigenden Panes und Views, welche keinerlei Bezug zu ihrem "inneren" Inhalt haben.

Die Wrapper-Funktion

Die Funktion wird einfach mit den erforderlichen Parametern aufgerufen, die benötigt werden, um eine Entität eindeutig zu identifizieren und zu rendern, Sie gibt das HTML der gerenderten und gecachten Entität zurück.

<?php
$html
= display_cache_get_rendered_entity($entity_type, $entity_id, $view_mode)
?>

Panels- und Views-Integration

Jetzt gibt es also die Möglichkeit. Doch sie wird nirgends genutzt. Alles rendert weiter fleißig vor sich hin. Daher müssen Views- und Panels-Plugins her, welche das Caching nutzen.

Display Cache bietet auf Grundlage von Entity API ein Ctools-Plugin, um eine Entity innerhalb eines Panes anzeigen zu können. Außerdem zwei Views-Plugins, ebenfalls auf Entity API basierend. Zum einen ein Row-Style Plugin und zum anderen einen Field Handler.

Hierdurch lassen sich alle angezeigten Entitäten cachen. Und wenn sich eine ändert, dann ändert sie sich halt! Und das gecachte HTML ändert sich automatisch mit!

Wenn ich das Modul einsetzen will, muss ich dann alle Views und Panels neu konfigurieren?

Sofern die Plugins, welche zur Anzeige der Entitäten verwendet werden, von Entity API bereitgestellt, wurden nicht. Es gibt die Option, diese Plugins von Display Cache überschreiben zu lassen.

Dynamische Inhalte

Werden während des Render-Prozesses dynamische Inhalte innerhalb einer Entität erzeugt (beispielsweise mit Voting API oder Flag), so werden diese selbstverständlich mit gecacht. Ebenfalls werden Java-Scripte, die mit drupal_add_js() innerhalb des Render-Prozesses generiert wurden, nicht wieder ausgeliefert.

Man könnte auch sagen: "sie funktionieren dann nicht mehr." Um dieses Problem zu beheben gibt es die Möglichkeit von zwei Alteration-Hooks.

<?php
hook_display_cache_pre_render_alter
(&$render_array, $context) {...}
?>

Dieser Hook ermöglicht die Manipulation des renderbaren Arrays vor dem tatsächlichen Rendern.

<?php
hook_display_cache_post_render_alter
(&$html, $context) {...}
?>

Dieser Hook ermöglicht das Manipulieren des auszuliefernden HTMLs. So können beispielsweise Tokens mit einem Flag-Widget ersetzt werden und/oder benötigte Javascripte ausgeliefert werden.

In beiden Fällen sind in $context die Informationen Entity Type, Entity ID sowie View Mode enthalten.

Dear Community

Wenn ihr es selbst ausprobieren wollt: Ich habe eine Sandbox von Display Cache auf Drupal.org angelegt, wo ihr den Quellcode beziehen könnt.

Nachdem ich nun alle meine Fragen selbst beantwortet habe, nun mal eine an euch: Was haltet ihr davon?