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

Introduzione all'Entity API in Drupal 8

30/09/2025, by Ivan

Sistema delle entità in Drupal 8

Le entità sono classi tipizzate con metodi

Metodi generici

$entity->id()

Metodi specifici del tipo di entità $node->getTitle()

 

Contesto

Il sistema delle entità è stato introdotto verso la fine del ciclo di sviluppo di Drupal 7 con standard di base per il caricamento delle entità. Il modulo entity.module ha ulteriormente esteso l’API, aggiungendo il supporto per il salvataggio e l’eliminazione delle entità e molti altri miglioramenti.

La maggior parte di questi miglioramenti è ora inclusa in Drupal 8. La validazione delle entità ora avviene nella propria API (che può validare un’entità salvata tramite REST invece che da un form, ad esempio).

Due varianti

I tipi di entità nel core sono di due varianti.

Oggetto di configurazione
Utilizza il Sistema di configurazione. Supporta le traduzioni e può fornire impostazioni personalizzate predefinite per le installazioni. Gli oggetti di configurazione sono memorizzati in una tabella condivisa del database di configurazione come righe.

Entità di contenuto
È composta da campi personalizzabili e di base, può avere revisioni e supporta le traduzioni. Gli oggetti di contenuto sono memorizzati in una tabella personalizzata del database come righe. Il nome della tabella corrisponde all’«id» dell’oggetto e le colonne sono definite dal metodo «baseFieldDefinitions» dell’oggetto.

Bundle

I bundle sono varianti di un tipo di entità. Ad esempio, per il tipo di entità nodo, i bundle sono diversi tipi di nodi come «articolo» e «pagina».

In generale, un bundle è rappresentato da un oggetto di configurazione, anche se nei moduli contrib esistono altri modelli. Quindi, nell’esempio del nodo, il tipo di nodo «article» è esso stesso un oggetto di configurazione. La configurazione memorizza le differenze tra tipi di oggetti di contenuto, come impostazioni e campi. Quando si crea un nuovo tipo di entità con bundle, si crea sia un’entità di contenuto, che gestirà i dettagli e le operazioni del contenuto, sia un oggetto di configurazione, che gestirà le differenze tra i tipi di entità di contenuto.

Annotazioni

Quando si crea un nuovo tipo di entità, è necessario utilizzare il sistema di annotazioni integrato nel core. Le annotazioni sembrano commenti docblock sopra la classe, ma vengono analizzate e memorizzate in cache dal core di Drupal. In molti modi le annotazioni sostituiscono alcuni degli stili più vecchi utilizzati in Drupal 7.

Parser di annotazioni

Le annotazioni vengono lette e analizzate a runtime dal meccanismo delle annotazioni. Drupal 8 utilizza il parser di annotazioni Doctrine, che le trasforma in un oggetto che può essere utilizzato da PHP.

Sintassi. La sintassi dell’annotazione è racchiusa in @ClassName(), consiste principalmente in coppie chiave/valore e può contenere array che usano parentesi graffe. Le chiavi di primo livello non devono essere racchiuse tra virgolette, mentre le chiavi degli array sì. Ogni coppia chiave/valore deve essere su una riga separata, e quella riga deve terminare con una virgola. Alcune funzioni possono essere eseguite sui valori, in particolare la funzione @Translation().

Esempio non funzionante di sintassi dell’annotazione:

/**
 * @ContentEntityType(
 *   id = "my_entity_type_id",
 *   label = @Translation("My entity type label"),
 *   example_pair = "this_examples_value",
 *   example_array = {
 *     "array_key" = "array_value",
 *     "some_other_key" = "some_other_value",
 *   },
 * )
 */

Annotazioni comuni di primo livello

Chiave = "Valore di esempio" Descrizione Variante di entità
id = "node",

Nome macchina per il tipo di oggetto.

Contenuto & Config
label = @Translation("Node"),

Nome leggibile per il tipo di oggetto.

Contenuto & Config
admin_permission = "administer nodes",

Il permesso che consente l’accesso amministrativo per configurare e gestire il tipo di oggetto. È necessario se la tua entità non definisce un gestore di «accesso».

Contenuto & Config
bundle_label = @Translation("Content type"),

Nome leggibile facoltativo per il tipo di oggetto del bundle.

Contenuto
bundle_entity_type = "node_type",

Quando si crea un oggetto di contenuto con bundle, questo valore deve essere l’«id» di un oggetto di configurazione. In questo caso «node_type» è un oggetto di configurazione.

Contenuto
base_table = "node",

Il nome della tabella del database per il tipo di oggetto.

Contenuto
fieldable = TRUE,

(boolean) Se questo tipo di entità può essere esteso tramite l’interfaccia utente dei campi.

Contenuto
field_ui_base_route = "entity.node_type.edit_form", Il nome della route a cui è legata l’interfaccia utente dei campi per l’oggetto disponibile per l’entità. Contenuto

 

Handler

Gli handler sono definiti nell’annotazione dell’oggetto come array. Supportano l’entità mappando parti specifiche della sua esecuzione in altre classi PHP. Queste classi «gestiscono» le parti assegnate dell’esecuzione dell’entità.

Storage - gestisce il caricamento, il salvataggio e l’eliminazione dell’oggetto. Per impostazione predefinita, le entità di contenuto usano Drupal\Core\Entity\Sql\SqlContentEntityStorage, mentre le entità di configurazione usano Drupal\Core\Config\Entity\ConfigEntityStorage. È possibile definire un handler di storage per estendere i metodi standard di archiviazione della propria entità. Potresti volerlo fare per fornire metodi aggiuntivi per raccogliere ID di revisione dell’entità o per determinare il numero di traduzioni che l’entità possiede.
Esempio: "storage" = "Drupal\node\NodeStorage",

Form - nell’annotazione degli handler di qualsiasi entità ci sono diversi handler di form che mappano le form di aggiunta, modifica ed eliminazione dell’entità in altre classi PHP.
Esempio:

"form" = {
  "add" = "Drupal\block\BlockForm",
  "edit" = "Drupal\block\BlockForm",
  "delete" = "Drupal\block\Form\BlockDeleteForm",
}

Inoltre, puoi definire una form «default» per gestire le form «add» ed «edit», invece di definirle separatamente. Vale la pena notare che la form «delete» quasi sempre sarà gestita da una classe separata dalle altre form. Questo perché la form di eliminazione è in genere una «form di conferma» che chiede semplicemente all’utente se è sicuro di voler eliminare l’oggetto.

View builder - questo handler fornisce una classe che gestirà l’output dell’entità quando viene visualizzata dall’utente finale. Ad esempio, visitando un nodo in un sito Drupal 8, l’output dell’entità è gestito dalla classe NodeViewBuilder.
Esempio: "view_builder" = "Drupal\node\NodeViewBuilder",

List builder - la classe list builder gestisce l’elenco degli oggetti a fini amministrativi. Questa classe definirà l’output delle intestazioni, delle righe e delle operazioni quando visiti la pagina di amministrazione delle entità. Ad esempio, visitando l’URI /admin/content del tuo sito Drupal, il contenuto della tabella è fornito dalla classe list builder dell’entità Node.
Esempio: "list_builder" = "Drupal\node\NodeListBuilder",

Route provider - handler opzionale che, se implementato, genera le route per gestire il tuo oggetto. L’implementazione di questo handler può sostituire la necessità di percorsi di entità definiti nel file routing.yml del tuo modulo. Nota che route_provider lavora insieme ai link definiti per la tua entità (vedi esempio più sotto nella sezione «Link»). L’annotazione route_provider è un array.
Esempio:

"route_provider" = {
  "html" = "Drupal\Core\Entity\Routing\AdminHtmlRouteProvider",
}

Access - l’handler di accesso può essere utilizzato per controlli dinamici dei permessi della tua entità. Si tratta di una mappatura a una classe che implementa EntityAccessControlHandlerInterface. Il core fornisce un’implementazione di questo interfaccia come EntityAccessControlHandler, ma per un controllo più accurato vorrai estendere questa classe con la tua.
Esempio: "access" = "NodeAccessControlHandler",

Views data - l’handler views_data consente a un’entità di estendere il modulo Views con dati personalizzati forniti dalla tua entità. Questo può servire ad aggiungere i baseFieldDefinitions della tua entità come campi Views, unire tabelle su relazioni di entità o altri cambiamenti relativi ai dati di Views.
Esempio: "views_data" = "Drupal\node\NodeViewsData",

Storage schema - l’handler storage_schema può essere implementato per modificare ulteriormente lo schema di archiviazione del database dell’oggetto. Ad esempio, aggiungendo ulteriori indici alle tabelle.
Esempio: "storage_schema" = "Drupal\node\NodeStorageSchema",

Translation - l’handler di traduzione può essere usato per modificare il modo in cui le form della tua entità interagiscono con le traduzioni.
Esempio: "translation" = "Drupal\node\NodeTranslationHandler",

Esempio completo di handler:
Il core di Drupal fornisce handler «out of the box» che puoi utilizzare, ma in molti casi vorrai estendere queste classi per avere maggiore controllo e personalizzazione della tua entità. In questo esempio è mostrata un’annotazione più completa degli handler usando le classi di base che puoi estendere.

handlers = {
  "view_builder" = "Drupal\Core\Entity\EntityViewBuilder",
  "list_builder" = "Drupal\Core\Entity\EntityListBuilder",
  "access" = "Drupal\Core\Entity\EntityAccessControlHandler",
  "views_data" = "Drupal\views\EntityViewsData",
  "storage" = "Drupal\Core\Entity\Sql\SqlContentEntityStorage",
  "storage_schema" = "Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema",
  "translation" = "Drupal\content_translation\ContentTranslationHandler",
  "form" = {
    "default" = "Drupal\Core\Entity\ContentEntityForm",
    "add" = "Drupal\Core\Entity\ContentEntityForm",
    "edit" = "Drupal\Core\Entity\ContentEntityForm",
    "delete" = "Drupal\Core\Entity\ContentEntityDeleteForm",
  },
  "route_provider" = {
    "html" = "Drupal\Core\Entity\Routing\AdminHtmlRouteProvider",
  },
},

Link

I link sono definiti nell’annotazione dell’oggetto con la sintassi array. I link hanno un set specifico di chiavi i cui valori sono URI dove puoi gestire il tipo di oggetto o le singole entità di quel tipo. Questi possono essere definiti sia per contenuto che per entità di configurazione.

Esempio:

id = "node",
handlers = {
  "route_provider" = {
    "html" = "Drupal\Core\Entity\Routing\AdminHtmlRouteProvider"
  }
},
links = {
  "canonical" = "/node/{node}",
  "add-page" = "/node/add",
  "add-form" = "/node/add/{node_type}",
  "edit-form" = "/node/{node}/edit",
  "delete-form" = "/node/{node}/delete",
  "collection" = "/admin/content",
},

Nota: questo non è preso parola per parola dal modulo Node, è solo un esempio.

Creare questi link non genera automaticamente route per questi URI. Per renderli disponibili, il tuo modulo deve implementare un file routing.yml o usare l’handler route_provider nell’annotazione dell’oggetto.

Link e route provider

I link sopra, lavorando insieme al «route_provider», renderanno disponibili a Drupal le seguenti route nominali:

Chiave del link Nome della route Esempio di URI di route Descrizione
canonical entity.node.canonical /node/1 Visualizza un nodo specifico
add-page entity.node.add_page /node/add Seleziona il tipo di nodo da aggiungere
add-form entity.node.add_form /node/add/article Aggiungi un nodo (di uno specifico bundle)
edit-form entity.node.edit_form /node/1/edit Modifica il form per un nodo specifico
delete-form entity.node.delete_form /node/1/delete Form di eliminazione per un nodo specifico
collection entity.node.collection /admin/content Visualizza tutti i nodi come elenco

 

Uso dei link
Questi link possono essere accessibili tramite il metodo toUrl() dell’oggetto:

$view_url_object = $entity->toUrl();  // Default is 'canonical'
$edit_url_string = $entity->toUrl('edit-form')->toString();

Risorse: