Entity prevod API
U Drupalu 8 je jezik polja uklonjen iz javnopristupnog API-ja, i polja se sada pridružuju objektima sa podrškom za jezik, od kojih „nasleđuju“ svoj jezik.
Glavne prednosti ovoga su:
- Nije potrebno brinuti o prenosivosti polja jer se time bavi entitet objekta interno.
// Na neki način odredite $active_langcode.
$translation = $entity->getTranslation($active_langcode);
$value = $translation->field_foo->value;
- Nije više potrebno prosleđivati aktivni jezik, zapravo možemo jednostavno proslediti objekat prevoda koji implementira EntityInterface i u stvari je klon izvornog objekta, ali sa drugačijim internim jezikom. To znači da u mnogim slučajevima kod ne mora znati jezik (osim ako to nije eksplicitno potrebno).
// Kreirajte odgovarajući objekat prevoda jednom i prosleđujte ga gde je potrebno.
// Ovo uglavnom rešavaju core podsistemi i u mnogim slučajevima eksplicitno dohvatanje
// objekta prevoda nije potrebno.
$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;
// obradite podatke
}
- Sada imamo ponovo upotrebljiv API za usklađivanje jezika entiteta, koji se može koristiti za određivanje prevoda entiteta koji je najprikladniji za određeni kontekst:
// Pojednostavljeni kod za generisanje renderabilnog niza za entitet.
function viewEntity(EntityInterface $entity, $view_mode = 'full', $langcode = NULL) {
// Metod EntityManagerInterface::getTranslationFromContext()
// primenjuje logiku usklađivanja jezika entiteta na ceo objekat
// i vraća odgovarajući objekat prevoda za dati kontekst.
// Parametar $langcode je opcion i označava jezik trenutnog konteksta.
// Ako nije naveden, koristi se trenutni jezik sadržaja,
// što je željeno ponašanje u fazi renderovanja.
// Polja sa praznim vrednostima se ne prikazuju.
$langcode = NULL;
$translation = $this->entityManager->getTranslationFromContext($entity, $langcode);
$build = entity_do_stuff($translation, 'full');
return $build;
}
Moguće je takođe navesti opcion parametar $context, koji može opisati kontekst u kojem će se koristiti objekat prevoda:
// Pojednostavljeni kod za generisanje zamena tokena.
function node_tokens($type, $tokens, array $data = array(), array $options = array()) {
$replacements = array();
// Ako za ovaj kontekst nije naveden jezik, podrazumevano se koristi
// podrazumevani jezik entiteta.
if (!isset($options['langcode'])) {
$langcode = Language::LANGCODE_DEFAULT;
}
// Prosleđujemo $context parametar koji opisuje operaciju koja se izvodi.
// Podrazumevana operacija je 'entity_view'.
$context = array('operation' => 'node_tokens');
$translation = \Drupal::service('entity.repository')->getTranslationFromContext($data['node'], $langcode, $context);
$items = $translation->get('body');
// obrađujte podatke
return $replacements;
}
Logika koja se koristi za određivanje koji objekat prevoda se vraća može biti menjana od strane modula. Pogledajte LanguageManager::getFallbackCandidates() za detaljnije informacije.
Stvarni podaci polja su raspoređeni među svim objektima prevoda, i izmena vrednosti neprevodivog polja automatski menja tu vrednost za sve objekte prevoda.
$entity->langcode->value = 'en';
$translation = $entity->getTranslation('it');
$en_value = $entity->field_foo->value; // $en_value je 'bar'
$it_value = $translation->field_foo->value; // $it_value je 'bella'
$entity->field_untranslatable->value = 'baz';
$translation->field_untranslatable->value = 'zio';
$value = $entity->field_untranslatable->value; // $value je 'zio'
U svakom trenutku može se kreirati instanca objekta prevoda iz izvornog objekta ili drugog objekta prevoda korišćenjem metode EntityInterface::getTranslation(). Ako je potreban aktivni jezik, može se dobiti preko EntityInterface::language(). Izvorni entitet se može dobiti preko EntityInterface::getUntranslated().
$entity->langcode->value = 'en';
$translation = $entity->getTranslation('it');
$langcode = $translation->language()->id; // $langcode je 'it'
$untranslated_entity = $translation->getUntranslated();
$langcode = $untranslated_entity->language()->id; // $langcode je 'en'
$identical = $entity === $untranslated_entity; // $identical je TRUE
$entity_langcode = $translation->getUntranslated()->language()->id; // $entity_langcode je 'en'
EntityInterface sada ima nekoliko metoda koji olakšavaju rad sa prevodima entiteta. Ako kod treba da deluje na svakom dostupnom prevodu, može koristiti EntityInterface::getTranslationLanguages():
foreach ($entity->getTranslationLanguages() as $langcode => $language) {
$translation = $entity->getTranslation($langcode);
entity_do_stuff($translation);
}
Postoje i metode za dodavanje prevoda, njegovo uklanjanje ili proveru da li prevod postoji:
if (!$entity->hasTranslation('fr')) {
$translation = $entity->addTranslation('fr', array('field_foo' => 'bag'));
}
// Što je ekvivalent sledećem kodu, mada ako je naveden nevalidan jezički kod, baca se izuzetak.
$translation = $entity->getTranslation('fr');
$translation->field_foo->value = 'bag';
// Pristup polju na uklonjenom objektu prevoda baca izuzetak.
$translation = $entity->getTranslation('it');
$entity->removeTranslation('it');
$value = $translation->field_foo->value; // baca InvalidArgumentException
Kada se prevodi entiteta dodaju u skladište ili uklanjaju iz njega, sledeći hookovi se pokreću:
- hook_entity_translation_insert()
- hook_entity_translation_delete()
Jezik polja je i dalje dostupan pozivom odgovarajuće metode samog objekta polja:
$langcode = $translation->field_foo->getLangcode();