0

I've got nodes with hero images. The hero images are a paragraph field with unlimited cardinality, each with an image and a translatable text. For design reasons I need to print the hero images in page.html.twig (using Twig Tweak for simplicity)

{{ drupal_field('field_banner_slide', 'node', node.id) }}

The hero slider has some options like timer, size,... which are other fields on the same host node, and pulled in during preprocess

function MYTHEME_base_preprocess_field(array &$variables, $hook) {
  $parentEntity = $element['#object'];

  if ($parentEntity && $variables['field_name'] == 'field_banner_slide') {
    // attach JS library
    // add HTML data attributes on this field based on other field values of same host node
    // ...and so on...
  }
}

All worked fine until my site went to the translator. My slider always returned the default lang. Next I tried setting the language in page.html.twig

{{ drupal_field('field_banner_slide', 'node', node.id, 'default', language.getId()) }}

This works for every other field - except Paragraphs. I've also tried the alternative

{{ node.field_banner_slide|view('default', language.getId()) }}

but still the same language problem.

I've already checked the source code from Twig Tweak, it seems to correctly set the language

  public function drupalField($field_name, $entity_type, $id = NULL, $view_mode = 'default', $langcode = NULL, $check_access = TRUE) {
    /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
    $entity = $id
      ? \Drupal::entityTypeManager()->getStorage($entity_type)->load($id)
      : \Drupal::routeMatch()->getParameter($entity_type);
    if ($entity && (!$check_access || $entity->access('view'))) {
      $entity = \Drupal::service('entity.repository')
        ->getTranslationFromContext($entity, $langcode);
      if (isset($entity->{$field_name})) {
        return $entity->{$field_name}->view($view_mode);
      }
    }
  }

I've been really digging here, but I can't find any single error. How do I get my correctly translated paragraphs?

PS: I don't want to use {{ drupal_entity('paragraph', my_field_banner_slide_target_ids, 'default', my_langcode) }}, because I also need the preprocessing from the host field.

0

The problem is that FieldItemInterface::view() has no language parameter. Furthermore paragraph fields are not translatable (only the subfields of the paragraph entity are translatable). So when rendering a paragraph field directly, without going through the host entity render stack, the language information is lost.

My solution was to force the translation in a preprocess function:

function MYTHEME_preprocess_field(array &$variables, $hook) {

  // field_banner_slide is a paragraph field which needs
  // translation AND is rendered directly, e.g. by using Twig Tweak's
  // {{ drupal_field('field_banner_slide', 'node', node.id) }} in page.html.twig
  //
  // don't to this for "normal" rendering, e.g. when using
  // {{ content.field_banner_slide }} in node.html.twig

  if ($variables['field_name'] == 'field_banner_slide') {
    $lang = \Drupal::languageManager()->getCurrentLanguage()->getId();
    if(count($variables['items'])) {
      foreach($variables['items'] as $key => $item) {
        if ($item['content']['#paragraph']->hasTranslation($lang)) {
          $variables['items'][$key]['content']['#paragraph'] = $item['content']['#paragraph']->getTranslation($lang);
        }
      }
    }
  }
}

For a better technical explanation see issue #2753201 on d.o

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.