Get translated field value with fallback

by Sebastian   Last Updated December 19, 2017 12:07 PM

How can I get the translated value of a field in Drupal 8 and if no translation is given, fallback to the default node language? I tried this:, but when no translation for a field if added, it just returns NULL.

Here is what I tried:

    $node = Node::load(2);
Tags : fields 8 i18n-l10n

Answers 2

You can try to provide the context for a fallback as 3rd parameter:

public EntityRepositoryInterface::getTranslationFromContext(EntityInterface $entity, $langcode = NULL, $context = array())

Here is the documentation, but it is not documented, what the content of the array is exactly:


I would code the fallback myself and take control, how this is handled exactly, if the node is not fully translated:

$val = \Drupal::service('entity.repository')->getTranslationFromContext($node)->field_my_awesome_field->value;
 if (empty($val)) {
    // $node has no translation with the default node language
    // get the default from somewhere else (domain, user ...) and try again
    $val = $node->getTranslation($defaultlanguage)->field_my_awesome_field->value;
if (empty($val)) {
   // someone needs to translate this node, in the meantime get the original value
   $val = $node->field_my_awesome_field->value;

You can adjust the code to your needs, you can add as many fallbacks as you like or go directly to the last if-statement to load the original field value.

One remark: If your multilingual site is setup correctly, this should not happen. The fallback is there, when something goes wrong. For example, if you configure a field as translatable, but when translating the node, you leave only this field blank. Then drupal does not know, is this intentionally, should it be blank or do you want to load the field from another language?

November 12, 2015 13:38 PM

Drupal 8 does not have built in field-level language fallbacks. That feature was removed in favor entity level language fallbacks since that is the common case. Usually an entity is translated as a while (or not) and it removes a huge amount of complexity, especially in views or so.

If you have a specific field where you want to apply this, then you need to implement that yourself. You can check if an entity-level translation exists with $node->hasTranslation('en') and if so, get it with $translation = $node->getTranslation('de') ($translation is still a node object, it's a clone of the original one with a different active language). Then check if you have a value and repeat until find one.

Something like this:

$value = NULL;
$language_manager = \Drupal::languageManager();
$current_langcode = $language_manager->getLanguage(Drupal\Core\Language\LanguageInterface::TYPE_CONTENT);
foreach ($language_manager->getFallbackCandidates(['langcode' => $language_manager->getLanguage(]) as $langcode) {
  if ($node->hasTranslation($langcode) && !$node->getTranslation($langcode)->field_my_awesome_field->isEmpty()) {
    $value = $node->getTranslation($langcode)->field_my_awesome_field->value;
November 12, 2015 21:34 PM

Related Questions