logo

Extra Block Types (EBT) - Nieuwe Layout Builder ervaring❗

Extra Block Types (EBT) - gestileerde, aanpasbare bloktypes: Slideshows, Tabs, Cards, Accordions en vele andere. Ingebouwde instellingen voor achtergrond, DOM Box, javascript-plugins. Ervaar vandaag al de toekomst van layout building.

Demo EBT-modules Download EBT-modules

❗Extra Paragraph Types (EPT) - Nieuwe Paragraphs ervaring

Extra Paragraph Types (EPT) - analoge op paragrafen gebaseerde set modules.

Demo EPT-modules Download EPT-modules

Scroll

CacheableDependencyInterface

03/10/2025, by Ivan

Om het werken met cachemetadata (cache tags, cache contexts en max-age) te vereenvoudigen, bestaat er in Drupal 8 het CacheableDependencyInterface.

Waarom?

Stel je voor dat je handmatig cache tags moet aanmaken voor elk individueel object en configuratie-object dat je gebruikt in een render array (of een andere berekening). En op een meertalige site moet je ook handmatig de nodige cachecontexten toevoegen (voor een vertaalde entiteit of een taaloverride voor een configuratie-object).

En niet alleen entiteiten en configuratie, maar ook toegangsresultaten, block-plugins, menulinks, context-plugins, condition-plugins enzovoort, omdat al die dingen uiteindelijk renderen (een specifiek type berekening) die we willen cachen.

In de beginperiode van de ontwikkeling van Drupal 8 was dit de realiteit. Het was duidelijk dat dit onbetrouwbaar was en zeer foutgevoelig.

Daarom werd het CacheableDependencyInterface geïntroduceerd. Zoals de naam al zegt: objecten die deze interface implementeren, kunnen automatisch cachebare afhankelijkheden worden.

Bijvoorbeeld: bij het renderen van een array met <p>Hallo, %user, welkom op %site!</p>, vertrouw je zowel op de User-entiteit van de huidige gebruiker als op de system.site-configuratie. Wanneer die render array wordt gecachet, heeft hij zowel deze user-entiteit als dit configuratie-object als cachebare afhankelijkheden.

CacheableDependencyInterface kan door elk value object worden geïmplementeerd (dus een object dat een logische eenheid van data vertegenwoordigt). Als je naar de API-documentatie kijkt, zie je dat dit door veel kernobjecten van Drupal 8 is geïmplementeerd. Sterker nog: het is veilig te zeggen dat het door de meeste objecten die je gebruikt in Drupal 8 wordt geïmplementeerd!

Er zijn twee veelvoorkomende uiterste gevallen, waarvoor Drupal handige traits aanbiedt: het geval van een onveranderlijk object dat dus permanent cachebaar is (UnchangingCacheableDependencyTrait, dat altijd max-age === permanent teruggeeft), en het geval van een object dat altijd dynamisch berekend wordt en dus nooit cachebaar is (UncacheableDependencyTrait, dat altijd max-age === 0 teruggeeft).

RefinableCacheableDependencyInterface

Maar CacheableDependencyInterface kan alleen werken met de ‘inherente’, ‘canonieke’ cachemetadata van een object. Soms bestaan er meerdere varianten van een object.

De bekendste voorbeelden hiervan zijn entiteitsvertalingen (dezelfde entiteit met hetzelfde entiteits-ID, enkel in een andere vertaling) en configuratievertalingen (hetzelfde configuratie-object met dezelfde naam, maar met een taaloverride).

In beide gevallen blijven de cachemetadata van het originele (niet-vertaalde) object gelden. Bijvoorbeeld de cache tags node:5. Maar — bij een entiteit — is er een extra taalcontext van content nodig (‘languages:’. LanguageInterface::TYPE_CONTENT, zie cachecontexten) om aan te geven dat deze entiteit een variant van de originele entiteit is die varieert afhankelijk van de ingestelde taalcontext. Evenzo is bij een configuratie-object de cachecontext van de interface-taal nodig (‘languages:’. LanguageInterface::TYPE_INTERFACE) om aan te geven dat dit een variant van het originele configuratie-object is.

Een ander voorbeeld is een “Pirate Day”-module die een override van configuratie toevoegt alleen op piratendag, met “yar”, “har” en willekeurige papegaaien; de configuratieobjecten zouden dan een pirate_day-cachecontext hebben.

In al deze voorbeelden moeten we onze cachemetadata verfijnen om de geladen variant te specificeren. Daarom bestaat het RefinableCacheableDependencyInterface, waarmee dit kan: het kan extra cache tags, contexten toevoegen en de max-age bijwerken.

Om dit eenvoudiger te maken, bestaat ook de RefinableCacheableDependencyTrait.

Over entiteiten en configuratieobjecten

Alle entiteiten in Drupal 8 (core, contrib & custom) implementeren het EntityInterface, dat zowel CacheableDependencyInterface als RefinableCacheableDependencyInterface uitbreidt. Bovendien breiden alle kernentiteiten de abstracte Entity-basis­klasse uit, en wordt aangeraden dat contrib/custom dat ook doet. Dit betekent dat elke entiteit waarmee je werkt automatisch consistente cache tags heeft (<entity type>:<entity ID>, bijvoorbeeld node:5 en user:3) en cachecontexten voor vertaling.

Alle configuratieobjecten in Drupal 8 breiden de abstracte ConfigBase-klasse uit, die zowel CacheableDependencyInterface als RefinableCacheableDependencyInterface implementeert. Dit betekent dat elk configuratieobject waarmee je werkt automatisch consistente cache tags heeft (in de vorm van config:<configuratie naam>, bijvoorbeeld config:system.performance) en cachecontexten voor configuratie-overrides (waarvan vertaling het enige kernvoorbeeld is).

Tot slot hebben alle entiteiten en configuratieobjecten in Drupal 8 automatisch cachecontexten voor respectievelijk content- en interface-taal, dankzij EntityManager::getTranslationFromContext() en LanguageConfigFactoryOverride::getCacheableMetadata($name).

Gebruik van objecten die cachebare afhankelijkheden zijn

Renderen is het meest voorkomende voorbeeld van afhankelijkheid van een object dat een cachebare afhankelijkheid is. Om dit te vereenvoudigen, is er RendererInterface::addCacheableDependency($build, $dependency) — waarbij $build een render array is die afhankelijk is van het object $dependency; de cachemetadata van het object worden automatisch overgenomen door de render array. Dit betekent dat de render array ongeldig wordt zodra een cache tag van het object ongeldig wordt, of een andere vertaling (content-taalcontext) gekozen wordt, en dat deze automatisch verloopt als de afhankelijkheid een beperkte max-age heeft.

Zie Cacheability van render arrays — concreet voorbeeld voor meer uitleg.

Een ander goed voorbeeld zijn toegangscontroles, die AccessResult-objecten teruggeven. Deze hebben ook een methode AccessResult::addCacheableDependency($dependency). Merk op dat we hier enkel $dependency doorgeven, omdat de cachemetadata van de afhankelijkheden rechtstreeks op het toegangsresultaat kunnen worden opgeslagen. (Renderen, met zijn render arrays, is de uitzondering.)

Gerelateerde interfaces en klassen

Zie ook