logo

Extra Block Types (EBT) - Nuova esperienza con Layout Builder❗

Extra Block Types (EBT) - tipi di blocchi stilizzati e personalizzabili: Slideshows, Tabs, Cards, Accordion e molti altri. Impostazioni integrate per sfondo, DOM Box, plugin javascript. Vivi oggi il futuro della costruzione dei layout.

Demo moduli EBT Scarica moduli EBT

❗Extra Paragraph Types (EPT) - Nuova esperienza con Paragraphs

Extra Paragraph Types (EPT) - insieme di moduli basati su paragrafi in modo analogo.

Demo moduli EPT Scarica moduli EPT

Scorri
03/10/2025, by Ivan

Per semplificare il lavoro con i metadati di cache (cache tags, cache contexts e max-age), in Drupal 8 esiste il CacheableDependencyInterface.

Perché?

Immaginate di dover creare manualmente i tag di cache per ogni singolo oggetto ed oggetto di configurazione che usate in un array di render (o in altri calcoli). E su un sito multilingua dover aggiungere manualmente anche i contesti di cache necessari (sia per un’entità tradotta sia per una configurazione con override linguistico).

E non solo entità e configurazione, ma anche risultati di accesso, plugin di blocco, link di menu, plugin contestuali, plugin di condizione ecc., perché tutti finiscono nel rendering (un tipo specifico di calcolo) che vogliamo mettere in cache.

Nei primi giorni di sviluppo di Drupal 8 questo era il caso. Era evidente che fosse inaffidabile e molto soggetto a errori.

Ecco perché è stato introdotto CacheableDependencyInterface. Come suggerisce il nome: gli oggetti che implementano questa interfaccia possono diventare automaticamente dipendenze cacheabili.

Ad esempio, quando si crea un array di render per <p>Ciao, %user, benvenuto su %site!</p>, ci si basa sia sull’entità User dell’utente corrente che sulla configurazione system.site. Quando questo array viene messo in cache, ha sia quell’utente che quell’oggetto di configurazione come dipendenze cacheabili.

CacheableDependencyInterface può essere implementato da qualsiasi oggetto valore (cioè un oggetto che rappresenta un’unità logica di dati). Se guardate la sua documentazione API, vedrete che è implementato da molti oggetti significativi nel core di Drupal 8. In realtà si può dire con sicurezza che sia implementato dalla maggior parte degli oggetti con cui interagite quando scrivete codice per Drupal 8!

Ci sono due casi opposti, piuttosto comuni, per cui Drupal fornisce trait pratici: il caso dell’oggetto immutabile e quindi cacheabile per sempre (UnchangingCacheableDependencyTrait, che restituisce sempre max-age === permanent) e il caso dell’oggetto sempre calcolato dinamicamente e quindi mai cacheato (UncacheableDependencyTrait, che restituisce sempre max-age === 0).

RefinableCacheableDependencyInterface

Ma CacheableDependencyInterface è in grado di lavorare solo con i metadati di cache “intrinseci” e “canonici” di un oggetto. A volte esistono più varianti di un oggetto.

Gli esempi più evidenti sono le traduzioni di entità (la stessa entità con lo stesso ID ma tradotta) e le traduzioni di configurazioni (lo stesso oggetto di configurazione con lo stesso nome ma con override linguistico).

In entrambi i casi, i metadati di cache dell’oggetto originale rimangono validi. Ad esempio, node:5 come tag di cache. Ma — nel caso di un’entità — è necessario aggiungere anche il contesto di cache per la lingua del contenuto (‘languages:’. LanguageInterface::TYPE_CONTENT, vedi Cache contexts), per indicare che si tratta di una variante che dipende dalla lingua del contenuto. Allo stesso modo, nel caso di un oggetto di configurazione serve il contesto di cache per la lingua dell’interfaccia (‘languages:’. LanguageInterface::TYPE_INTERFACE) per indicare che l’oggetto varia in base alla lingua dell’interfaccia.

Un esempio oltre le traduzioni: un modulo “Giornata del Pirata” che applica override di configurazione solo in quella giornata, aggiungendo yar, har e pappagalli random; in questo caso le configurazioni avranno il contesto di cache pirate_day.

In tutti questi esempi dobbiamo raffinare i metadati di cache per indicare la variante caricata. Per questo è stato introdotto il RefinableCacheableDependencyInterface, che consente di aggiungere tag, contesti e aggiornare il max-age.

Per semplificarne l’implementazione, esiste anche RefinableCacheableDependencyTrait.

Su entità e oggetti di configurazione

Tutte le entità in Drupal 8 (core, contrib e custom) implementano EntityInterface, che estende sia CacheableDependencyInterface che RefinableCacheableDependencyInterface. Inoltre, tutte le entità del core estendono Entity come classe base, e lo stesso è consigliato per le custom/contrib. Questo significa che ogni entità ha automaticamente tag di cache coerenti (<entity type>:<entity ID>, es. node:5, user:3) e i contesti di cache per riflettere le traduzioni.

Tutti gli oggetti di configurazione nel core estendono ConfigBase, che implementa sia CacheableDependencyInterface sia RefinableCacheableDependencyInterface. Ciò significa che ogni oggetto di configurazione ha automaticamente tag di cache (del tipo config:<configuration name>, es. config:system.performance) e i contesti per riflettere override linguistici.

Infine, tutte le entità e configurazioni in Drupal 8 hanno automaticamente i contesti di cache di lingua (contenuto/interfaccia) grazie a EntityManager::getTranslationFromContext() e LanguageConfigFactoryOverride::getCacheableMetadata().

Uso di oggetti cacheabili come dipendenze

Il rendering è l’esempio più comune. Per facilitarlo, c’è RendererInterface::addCacheableDependency($build, $dependency): dove $build è un render array che dipende dall’oggetto $dependency; i suoi metadati di cache saranno automaticamente incorporati. Ciò significa che l’array sarà invalidato quando i tag di cache cambiano, varierà quando cambiano i contesti (es. lingua) ed espirerà automaticamente se la dipendenza ha un max-age limitato.

Vedi Cacheability dei render array — esempio concreto.

Un altro esempio sono i controlli di accesso che ritornano oggetti AccessResult, che hanno anche AccessResult::addCacheableDependency($dependency). Qui c’è solo $dependency perché i metadati possono essere mantenuti sull’oggetto stesso.

Interfacce e classi correlate

Vedi anche