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
30/09/2025, by Ivan

In Drupal 8 la lingua dei campi non è più fornita tramite l’API pubblica, invece i campi sono collegati ad oggetti con supporto multilingua, dai quali «ereditano» la loro lingua.

I principali vantaggi qui sono:

  • Non dobbiamo preoccuparci della portabilità dei campi, poiché se ne occupa l’oggetto entità internamente.
// Determina in qualche modo il $active_langcode.
$translation = $entity->getTranslation($active_langcode);
$value = $translation->field_foo->value;
  • Non dobbiamo più passare la lingua attiva, in realtà possiamo semplicemente passare l’oggetto traduzione, che implementa EntityInterface ed è effettivamente un clone dell’oggetto originale, solo con un’altra lingua interna. Questo significa che in molti casi il codice risultante potrebbe non dover conoscere la lingua (a meno che non sia rilevante per logica esplicita).
// Istanzia l’oggetto traduzione corretto una sola volta e passalo ovunque
// sia necessario. Di solito i sottosistemi core se ne occupano e in molti casi
// non serve un recupero esplicito dell’oggetto traduzione.
$langcode = Drupal::languageManager()->getLanguage(Language::TYPE_CONTENT);
$translation = $entity->getTranslation($langcode);
entity_do_stuff($translation);

function entity_do_stuff(EntityInterface $entity) {
  $value = $entity->field_foo->value;
  // fai cose
}
  • Ora abbiamo un’API di negoziazione linguistica riutilizzabile a livello di entity, che può essere usata per determinare la traduzione più adatta per un contesto specifico:
// Codice semplificato per generare un array renderizzabile per un’entità.
function viewEntity(EntityInterface $entity, $view_mode = 'full', $langcode = NULL) {
  // Il metodo EntityManagerInterface::getTranslationFromContext()
  // applicherà la logica di negoziazione della lingua a tutto l’oggetto entità
  // e restituirà l’oggetto traduzione corretto per il contesto dato.
  // Il parametro $langcode è opzionale e indica la lingua del contesto corrente.
  // Se non è specificato viene usata la lingua dei contenuti corrente, che è
  // il comportamento desiderato in fase di rendering.
  // Nota che i valori dei campi restano invariati, quindi i valori vuoti
  // semplicemente non verranno mostrati.
  $langcode = NULL;
  $translation = $this->entityManager->getTranslationFromContext($entity, $langcode);
  $build = entity_do_stuff($translation, 'full');
  return $build;
}

Possiamo anche specificare un parametro opzionale $context, che può descrivere il contesto in cui verrà usato l’oggetto traduzione:

// Codice semplificato per generare sostituzioni di token.
function node_tokens($type, $tokens, array $data = array(), array $options = array()) {
  $replacements = array();

  // Se non è specificata alcuna lingua per questo contesto usiamo
  // la lingua predefinita dell’entità.
  if (!isset($options['langcode'])) {
    $langcode = Language::LANGCODE_DEFAULT;
  }

  // Passiamo un parametro $context che descrive l’operazione eseguita.
  // L’operazione predefinita è 'entity_view'.
  $context = array('operation' => 'node_tokens');
  $translation = \Drupal::service('entity.repository')->getTranslationFromContext($data['node'], $langcode, $context);
  $items = $translation->get('body');

  // fai cose

  return $replacements;
}

La logica usata per determinare l’oggetto traduzione restituito può essere modificata dai moduli. Vedi LanguageManager::getFallbackCandidates() per maggiori dettagli.

I dati effettivi dei campi sono condivisi tra tutti gli oggetti traduzione e la modifica di un campo non traducibile lo cambia automaticamente per tutte le traduzioni.

$entity->langcode->value = 'en';
$translation = $entity->getTranslation('it');

$en_value = $entity->field_foo->value; // $en_value è 'bar'
$it_value = $translation->field_foo->value; // $it_value è 'bella'

$entity->field_untranslatable->value = 'baz';
$translation->field_untranslatable->value = 'zio';
$value = $entity->field_untranslatable->value; // $value è 'zio'

In qualsiasi momento è possibile creare un’istanza di oggetto traduzione dall’entità originale o da un’altra traduzione usando il metodo EntityInterface::getTranslation(). Se è necessario conoscere esplicitamente la lingua attiva, la si può ottenere con EntityInterface::language(). L’entità non tradotta si può ottenere con EntityInterface::getUntranslated().

$entity->langcode->value = 'en';

$translation = $entity->getTranslation('it');
$langcode = $translation->language()->id; // $langcode è 'it';

$untranslated_entity = $translation->getUntranslated();
$langcode = $untranslated_entity->language()->id; // $langcode è 'en';

$identical = $entity === $untranslated_entity; // $identical è TRUE

$entity_langcode = $translation->getUntranslated()->language()->id; // $entity_langcode è 'en'

EntityInterface ora ha diversi metodi che semplificano il lavoro con le traduzioni delle entità. Se un frammento di codice deve agire per ogni traduzione disponibile, può usare EntityInterface::getTranslationLanguages():

foreach ($entity->getTranslationLanguages() as $langcode => $language) {
  $translation = $entity->getTranslation($langcode);
  entity_do_stuff($translation);
}

Ci sono anche modi per aggiungere una traduzione, rimuoverla o verificarne l’esistenza:

if (!$entity->hasTranslation('fr')) {
  $translation = $entity->addTranslation('fr', array('field_foo' => 'bag'));
}

// Equivalente al seguente codice, anche se se viene specificato
// un codice lingua non valido viene lanciata un’eccezione.
$translation = $entity->getTranslation('fr');
$translation->field_foo->value = 'bag';

// Accedere a un campo su un oggetto traduzione rimosso genera un’eccezione.
$translation = $entity->getTranslation('it');
$entity->removeTranslation('it');
$value = $translation->field_foo->value; // lancia InvalidArgumentException

Quando le traduzioni di un’entità vengono aggiunte o rimosse dallo storage, vengono invocati i seguenti hook:

  • hook_entity_translation_insert()
  • hook_entity_translation_delete()

La lingua di un campo può comunque essere ottenuta richiamando il metodo appropriato sull’oggetto campo stesso:

$langcode = $translation->field_foo->getLangcode();