Entity Translation API
Drupal 8 में फील्ड की भाषा अब Public API द्वारा उपलब्ध नहीं कराई जाती, बल्कि फील्ड्स को language-aware ऑब्जेक्ट्स से जोड़ा जाता है, जिनसे वे अपनी भाषा “inherit” करते हैं।
इसके मुख्य फायदे हैं:
- हमें फील्ड पोर्टेबिलिटी की चिंता नहीं करनी पड़ती, क्योंकि इसका ध्यान entity ऑब्जेक्ट खुद रखता है।
// किसी तरह $active_langcode निर्धारित करें। $translation = $entity->getTranslation($active_langcode); $value = $translation->field_foo->value;
- हमें अब active language पास करने की ज़रूरत नहीं है, बल्कि हम translation ऑब्जेक्ट पास कर सकते हैं, जो EntityInterface को implement करता है और असल में मूल ऑब्जेक्ट का clone होता है, बस अलग internal language के साथ। इसका मतलब है कि कई मामलों में कोड को language के बारे में पता भी नहीं होगा (बिल्कुल, अगर ज़रूरी न हो तो)।
// सही translation ऑब्जेक्ट एक बार बनाइए और जहाँ ज़रूरत हो वहाँ पास कीजिए।
// Core subsystems आमतौर पर इस काम का ध्यान रखते हैं और कई common मामलों
// में translation ऑब्जेक्ट को explicitly प्राप्त करने की ज़रूरत नहीं होती।
$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;
// do stuff
}
- अब हमारे पास entity language negotiation के लिए एक reusable API है, जो किसी खास context के लिए सबसे उपयुक्त translation object तय करने में मदद करता है:
// किसी entity के लिए renderable array बनाने का simplified कोड।
function viewEntity(EntityInterface $entity, $view_mode = 'full', $langcode = NULL) {
// EntityManagerInterface::getTranslationFromContext() पूरा entity object लेकर
// language negotiation logic लागू करेगा और context के हिसाब से सही translation
// object लौटाएगा।
// $langcode parameter वैकल्पिक है और current context की language को दर्शाता है।
// अगर निर्दिष्ट न हो तो current content language उपयोग होगी।
$langcode = NULL;
$translation = $this->entityManager->getTranslationFromContext($entity, $langcode);
$build = entity_do_stuff($translation, 'full');
return $build;
}
हम एक वैकल्पिक $context parameter भी पास कर सकते हैं, जो बताएगा कि translation object किस context में उपयोग होगा:
// Simplified token replacements generation code.
function node_tokens($type, $tokens, array $data = array(), array $options = array()) {
$replacements = array();
// अगर इस context के लिए language नहीं दी गई, तो default entity language का उपयोग होगा।
if (!isset($options['langcode'])) {
$langcode = Language::LANGCODE_DEFAULT;
}
// हम $context parameter पास करते हैं, जो operation का वर्णन करता है।
// Default operation है 'entity_view'।
$context = array('operation' => 'node_tokens');
$translation = \Drupal::service('entity.repository')->getTranslationFromContext($data['node'], $langcode, $context);
$items = $translation->get('body');
// do stuff
return $replacements;
}
यह तय करने के लिए उपयोग की जाने वाली logic modules द्वारा बदली जा सकती है। अधिक जानकारी के लिए देखें LanguageManager::getFallbackCandidates()।
फील्ड का actual डेटा सभी translation objects के बीच साझा होता है, और किसी untranslatable फील्ड का मान बदलने से यह सभी translation objects में बदल जाता है।
$entity->langcode->value = 'en';
$translation = $entity->getTranslation('it');
$en_value = $entity->field_foo->value; // $en_value is 'bar'
$it_value = $translation->field_foo->value; // $it_value is 'bella'
$entity->field_untranslatable->value = 'baz';
$translation->field_untranslatable->value = 'zio';
$value = $entity->field_untranslatable->value; // $value is 'zio'
किसी भी समय translation object को मूल object या किसी अन्य translation object से EntityInterface::getTranslation() द्वारा प्राप्त किया जा सकता है। अगर active language ज़रूरी है, तो EntityInterface::language() द्वारा पाई जा सकती है। मूल entity को EntityInterface::getUntranslated() से प्राप्त किया जा सकता है।
$entity->langcode->value = 'en';
$translation = $entity->getTranslation('it');
$langcode = $translation->language()->id; // $langcode is 'it';
$untranslated_entity = $translation->getUntranslated();
$langcode = $untranslated_entity->language()->id; // $langcode is 'en';
$identical = $entity === $untranslated_entity; // $identical is TRUE
$entity_langcode = $translation->getUntranslated()->language()->id; // $entity_langcode is 'en'
EntityInterface में अब कई methods हैं, जो entity translations के साथ काम करना आसान बनाते हैं। अगर कोड के किसी हिस्से को सभी translations पर लागू होना है, तो वह EntityInterface::getTranslationLanguages() का उपयोग कर सकता है:
foreach ($entity->getTranslationLanguages() as $langcode => $language) {
$translation = $entity->getTranslation($langcode);
entity_do_stuff($translation);
}
हम translation जोड़ सकते हैं, हटा सकते हैं या उसकी उपलब्धता जाँच सकते हैं:
if (!$entity->hasTranslation('fr')) {
$translation = $entity->addTranslation('fr', array('field_foo' => 'bag'));
}
// यह इसके बराबर है, लेकिन अगर invalid language code दिया तो exception फेंका जाएगा।
$translation = $entity->getTranslation('fr');
$translation->field_foo->value = 'bag';
// हटाए गए translation object के किसी फील्ड को एक्सेस करने पर exception फेंका जाएगा।
$translation = $entity->getTranslation('it');
$entity->removeTranslation('it');
$value = $translation->field_foo->value; // throws InvalidArgumentException
जब entity translations storage में जोड़े या हटाए जाते हैं, तो ये hooks ट्रिगर होते हैं:
- hook_entity_translation_insert()
- hook_entity_translation_delete()
फील्ड की भाषा अब भी field object के method द्वारा प्राप्त की जा सकती है:
$langcode = $translation->field_foo->getLangcode();