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
Contesti di cache = dipendenze contestuali (della richiesta)
I contesti di cache sono simili all’intestazione HTTP Vary.

Perché?

I contesti di cache definiscono il modo di creare varianti dipendenti dal contesto di qualcosa che deve essere memorizzato nella cache. Il codice che crea cache diventa più leggibile e la stessa logica non deve essere ripetuta in ogni posto in cui sono necessarie le stesse variazioni di contesto.

Esempi:

  • L’output di alcuni dati dipende dal tema attivo e risultati diversi vengono mostrati per temi diversi. In questo caso si usa la cache in base al contesto di cache del tema.
  • Quando si costruisce un array di rendering che mostra un messaggio personalizzato, il rendering dell’array dipende dall’utente. Allora la cache dipenderà dal contesto di cache dell’utente.
  • In generale: quando alcune informazioni costose da calcolare dipendono dall’ambiente del server, si usa un contesto di cache anche per questo.

Come?

Un contesto di cache è una stringa che fa riferimento a uno dei servizi di contesto di cache disponibili (vedi sotto).

I contesti di cache vengono passati come insiemi (l’ordine non conta) di stringhe, quindi sono espressi come string[]. Sono insiemi perché un singolo elemento di cache può dipendere (variare) da più contesti di cache.

Di solito i contesti di cache provengono dall’oggetto di contesto della richiesta (cioè dalla request). Gran parte dell’ambiente per un’applicazione web è ottenuto dal contesto della richiesta. In fin dei conti, le risposte HTTP vengono generate in larga misura in base alle proprietà delle richieste HTTP che le hanno avviate.

Ma questo non significa che i contesti di cache debbano provenire solo dalla richiesta – possono anche dipendere dal codice distribuito, ad esempio il contesto deployment_id.

In secondo luogo, i contesti di cache sono descritti come gerarchie. L’esempio più semplice: quando qualcosa varia per ogni utente, non serve più usare solo i permessi, perché le differenze sono già per utente. Per un set di permessi, la cache viene usata per ciascun permesso. Se una parte della pagina varia per utente e un’altra per permessi, Drupal deve essere abbastanza intelligente da usare le differenze solo per utente. Qui entra in gioco l’informazione gerarchica dei contesti di cache, per evitare variazioni inutili della cache.

Sintassi

  • I punti separano elementi genitori dai figli
  • Il nome del contesto al plurale indica che può essere usato un parametro: aggiungere i due punti e il parametro desiderato (se non specificato, verranno raccolti tutti i possibili parametri, ad esempio tutti gli argomenti della query)

Contesti di cache del core di Drupal 8

Il core di Drupal 8 fornisce la seguente gerarchia di contesti di cache:

cookies
  :name
headers
  :name
ip
languages
  :type
protocol_version // Disponibile in 8.9.x o superiore.
request_format
route
  .book_navigation
  .menu_active_trails
    :menu_name
  .name
session
  .exists
theme
timezone
url
  .path
    .is_front // Disponibile in 8.3.x o superiore.
    .parent
  .query_args
    :key
    .pagers
      :pager_id
  .site
user
  .is_super_user
  .node_grants
    :operation
  .permissions
  .roles
    :role

Nota: per usare il contesto di cache url.path.is_front in rami/versioni precedenti, vedi questa change record.

Ovunque si usino i contesti di cache, si usa questa intera gerarchia, che ha 3 vantaggi:

  • nessuna ambiguità: è chiaro su cosa si basa il contesto di cache genitore
  • il confronto (e la riduzione) dei contesti diventa più semplice: se sono presenti sia a.b.c che a.b, è evidente che a.b include a.b.c, e quindi è chiaro perché a.b.c può essere omesso
  • non è necessario preoccuparsi che ogni livello dell’albero sia unico nell’intero albero

Esempi di contesti di cache da questa gerarchia:

  • theme (dipende dal tema impostato)
  • user.roles (dipende dalla combinazione di ruoli)
  • user.roles:anonymous (dipende dal fatto che l’utente attuale abbia il ruolo “anonimo” o meno)
  • languages (varia per tutti i tipi di lingua: interfaccia, contenuto…)
  • languages:language_interface (dipende dalla lingua dell’interfaccia)
  • languages:language_content (dipende dalla lingua del contenuto)
  • url (dipende dall’intero URL)
  • url.query_args (dipende da tutta la query string)
  • url.query_args:foo (dipende dall’argomento di query ?foo)
  • protocol_version (dipende da HTTP/1 vs HTTP/2)

Ottimizzazione/riduzione/unione dei contesti di cache

Drupal usa automaticamente l’informazione gerarchica per semplificare i contesti. Per esempio, quando una parte della pagina varia per utente (user) e un’altra parte varia per permessi (user.permissions), non ha senso differenziare ulteriormente per permessi, dato che già varia per utente.
In altre parole: optimize([user, user.permissions]) = [user].

I contesti di cache che dipendono da configurazioni che possono cambiare nel tempo legano anche metadati di cache: tag di cache e max-age. Così, quando questi contesti sono ottimizzati, i loro tag restano associati. Se i permessi cambiano, l’elemento di cache viene invalidato.

Un esempio più complesso sono i node grants. Essi dipendono da un utente specifico, quindi il contesto è user.node_grants. Ma i node grants possono essere estremamente dinamici (possono cambiare ogni pochi minuti). Quindi, spesso, max-age = 0. In questo caso: optimize([user, user.node_grants]) = [user, user.node_grants].

Come riconoscerli, definirli e crearli?

I contesti di cache sono servizi taggati come cache.context. Qualsiasi modulo può aggiungerne. Implementano \Drupal\Core\Cache\Context\CacheContextInterface o \Drupal\Core\Cache\Context\CalculatedCacheContextInterface (per i contesti che accettano parametri).

Per vedere tutti i contesti disponibili puoi cercare le implementazioni di queste interfacce nella tua IDE, oppure usare la Drupal Console:

$ drupal debug:cache:context

Debug

Quando qualcosa viene memorizzato in cache con contesti, questi contesti fanno parte del CID della cache. Ad esempio: foo:bar:[languages:language_interface]=en:[user.permissions]=HASH:[route]=myroute.HASH.

Intestazioni (debug)

È facile vedere da quali contesti dipende una risposta: basta guardare l’intestazione X-Drupal-Cache-Contexts.

Cache dinamica della pagina

L’uso esteso dei contesti di cache in Drupal 8 consente al core di fornire la cache dinamica della pagina abilitata per default.

Cache interna della pagina

Nota: la cache interna della pagina presuppone che tutte le pagine servite agli utenti anonimi siano identiche, indipendentemente dai contesti di cache. Se vuoi usare contesti di cache per differenziare il contenuto per utenti anonimi, questo modulo deve essere disabilitato.

Vedi anche