Entity Translation API
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.