logo

Extra Block Types (EBT) - Neue Erfahrung im Layout Builder❗

Extra Block Types (EBT) - gestylte, anpassbare Blocktypen: Diashows, Registerkarten, Karten, Akkordeons und viele andere. Eingebaute Einstellungen für Hintergrund, DOM Box, Javascript Plugins. Erleben Sie die Zukunft der Layouterstellung schon heute.

Demo EBT-Module EBT-Module herunterladen

❗Extra Absatztypen (EPT) - Erfahrung mit neuen Absätzen

Extra Paragraph Types (EPT) - analoger, auf Absätzen basierender Satz von Modulen.

Demo EPT-Module EPT-Module herunterladen

Scroll
18/06/2025, by Ivan

In Drupal 8 wird die Sprache von Feldern nicht mehr über die öffentliche API bereitgestellt, stattdessen sind Felder an sprachunterstützende Objekte angehängt, von denen sie ihre Sprache „erben“.

Die wichtigsten Vorteile sind dabei:

  • Wir müssen uns nicht um die Sprachzuordnung der Felder kümmern, da dies vom Entity-Objekt intern gehandhabt wird.
      // Bestimmen Sie auf irgendeine Weise den $active_langcode.
      $translation = $entity->getTranslation($active_langcode);
      $value = $translation->field_foo->value;
  • Wir müssen den aktiven Sprachcode nicht mehr übergeben, sondern können einfach das Übersetzungsobjekt verwenden, das EntityInterface implementiert und im Grunde ein Klon des Original-Objekts mit anderer interner Sprache ist. Das bedeutet, dass der Code in vielen Fällen keine Kenntnis von der Sprache benötigt (außer er bezieht sich explizit darauf).
      // Instanziiere das passende Übersetzungsobjekt nur einmal und übergebe es überall,
      // wo es benötigt wird. Dies wird typischerweise von Core-Subsystemen erledigt,
      // sodass eine explizite Abfrage meist nicht nötig ist.
      $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;
        // tue etwas
      }
  • Wir haben nun eine wiederverwendbare API für die Sprachverhandlung auf Entity-Ebene, mit der wir die passendste Übersetzung für einen bestimmten Kontext bestimmen können:
      // Vereinfachter Code zur Erstellung eines renderbaren Arrays für eine Entity.
      function viewEntity(EntityInterface $entity, $view_mode = 'full', $langcode = NULL) {
        // Die Methode EntityManagerInterface::getTranslationFromContext() wendet
        // die Sprachverhandlungslogik auf die gesamte Entity an und liefert
        // das passende Übersetzungsobjekt für den gegebenen Kontext zurück.
        // Der Parameter $langcode ist optional und gibt die Sprache des
        // aktuellen Kontexts an. Wird er nicht angegeben, wird die
        // aktuelle Inhaltssprache verwendet, was in der Renderphase gewünscht ist.
        // Beachten Sie, dass Feldwerte nicht verändert werden; leere Werte
        // werden einfach nicht angezeigt.
        $langcode = NULL;
        $translation = $this->entityManager->getTranslationFromContext($entity, $langcode);
        $build = entity_do_stuff($translation, 'full');
        return $build;
      }

Wir können auch einen optionalen Parameter $context angeben, um den Kontext zu beschreiben, in dem das Übersetzungsobjekt verwendet wird:

      // Vereinfachter Code zur Erzeugung von Token-Ersetzungen.
      function node_tokens($type, $tokens, array $data = array(), array $options = array()) {
        $replacements = array();

        // Wenn keine Sprache für diesen Kontext angegeben ist, verwenden wir
        // die Standardsprache der Entity.
        if (!isset($options['langcode'])) {
          $langcode = Language::LANGCODE_DEFAULT;
        }

        // Wir übergeben einen $context-Parameter, der die durchgeführte
        // Operation beschreibt. Die Standardoperation ist 'entity_view'.
        $context = array('operation' => 'node_tokens');
        $translation = \Drupal::service('entity.repository')->getTranslationFromContext($data['node'], $langcode, $context);
        $items = $translation->get('body');

        // mache etwas

        return $replacements;
      }

Die Logik, die das zurückgegebene Übersetzungsobjekt bestimmt, kann durch Module verändert werden. Siehe LanguageManager::getFallbackCandidates() für Details.

Die eigentlichen Feldwerte sind über alle Übersetzungsobjekte verteilt, und Änderungen an einem nicht übersetzbaren Feld wirken sich automatisch auf alle Übersetzungen aus.

  $entity->langcode->value = 'en';
  $translation = $entity->getTranslation('it');
  
  $en_value = $entity->field_foo->value; // $en_value ist 'bar'
  $it_value = $translation->field_foo->value; // $it_value ist 'bella'

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

Jederzeit kann eine Instanz eines Übersetzungsobjekts aus dem Originalobjekt oder einem anderen Übersetzungsobjekt über die Methode EntityInterface::getTranslation() erzeugt werden. Wenn der aktive Sprachcode explizit benötigt wird, kann er über EntityInterface::language() abgefragt werden. Das Originalobjekt kann über EntityInterface::getUntranslated() abgerufen werden.

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

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

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

  $identical = $entity === $untranslated_entity; // $identisch ist TRUE

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

EntityInterface verfügt jetzt über mehrere Methoden, die die Arbeit mit Entity-Übersetzungen erleichtern. Wenn ein Code-Abschnitt für jede verfügbare Übersetzung ausgeführt werden soll, kann EntityInterface::getTranslationLanguages() verwendet werden:

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

Es gibt auch Methoden zum Hinzufügen, Entfernen oder Prüfen von Übersetzungen:

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

  // Das entspricht folgendem Code, wobei eine Ausnahme geworfen wird, wenn
  // ein ungültiger Sprachcode angegeben wird.
  $translation = $entity->getTranslation('fr');
  $translation->field_foo->value = 'bag';

  // Der Zugriff auf ein Feld eines entfernten Übersetzungsobjekts löst eine
  // Ausnahme aus.
  $translation = $entity->getTranslation('it');
  $entity->removeTranslation('it');
  $value = $translation->field_foo->value; // wirft InvalidArgumentException

Wenn Übersetzungen einer Entity hinzugefügt oder daraus entfernt werden, werden folgende Hooks ausgelöst:

  • hook_entity_translation_insert()
  • hook_entity_translation_delete()

Die Sprache eines Feldes kann weiterhin durch den entsprechenden Methodenaufruf am Feldobjekt abgefragt werden:

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

 

Drupal’s online documentation is © 2000-2020 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution-ShareAlike 2.0. PHP code is distributed under the GNU General Public License.