1

I made a custom controller that load a paragraph field from a node and then render some part in a template. The paragraph field field_title and field_description are translatable.

The translation works fine on the admin side. I followed https://www.drupal.org/docs/8/modules/paragraphs/multilingual-paragraphs-configuration and I can see the content is translated from the admin. But my controller only loads the default language value instead of the current language.

<?php

/**
 * @file
 * Contains \Drupal\MyModule\Controller\MyModuleController.
 */

namespace Drupal\MyModule\Controller;

use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;

class MyModuleController extends ControllerBase {
    
    /**
     * Controller load the game
     * 
     * @return \Drupal\MyModule\Controller\RedirectResponse
     */
    public function gameView() {
        
        $nid = 1;
        
        // Load the game
        $game = \Drupal::entityTypeManager()->getStorage('node')->load($nid);
                
        $stages = [];
        
        // Get all the stages of the game
        $paragraph_field_items = $game->get('field_stages')->getValue();
        if (!$paragraph_field_items) {
            throw new \Symfony\Component\HttpKernel\Exception\NotFoundHttpException('This game has no level');
        }
            
        // Get storage for paragraph
        $paragraph_storage = \Drupal::entityTypeManager()->getStorage('paragraph');
        // Collect paragraph field's ids.
        $ids = array_column($paragraph_field_items, 'target_id');
        // Load all paragraph objects.
        $paragraphs_objects = $paragraph_storage->loadMultiple($ids);

        /** @var \Drupal\paragraphs\Entity\Paragraph $paragraph */
        foreach ($paragraphs_objects as $paragraph) {
          // Get field from the paragraph.

          $description = [
              '#type' => 'processed_text',
              '#text' => $paragraph->get('field_description')->value,
              '#format' => 'basic_html',
          ];

          $stages [] = [
              'title' => $paragraph->get('field_title')->value,
              'image' => $paragraph->get('field_image'),
              'description' => $description,
              'east_lv95' => $paragraph->get('field_east_lv95')->value,
              'north_lv95' => $paragraph->get('field_north_lv95')->value,
          ];
        }
        
                  
        return [
            '#theme' => 'game_map',
            '#party' => $party,
            '#stages' => $stages,
            '#game' => $game,
        ];
    }
2
  • 1
    This might be helpful drupal.stackexchange.com/questions/269468/… – 4k4 Aug 12 '20 at 13:19
  • After you loaded the $game with the entity type manager, load the translation with the entity repository: $game = \Drupal::service('entity.repository')->getTranslationFromContext($game);. So you just have to add this one line to the code you already have. And maybe consider injecting the services instead, since \Drupal calls should be avoided. – leymannx Aug 12 '20 at 14:52
1

Based on the comments I changed $game->get('field_stages')->getValue(); for $game->get('field_stages')->referencedEntities();. This allow me to greatly simply a part of the code.

To load the correct language I added $paragraph = \Drupal::service('entity.repository')->getTranslationFromContext($paragraph); inside the loop. Using getTranslationFromContext on the $game didn't works for the paragraph.

I'm not 100% satisfied as I feel translation should be loaded directly when all the fields are loaded with referencedEntities(). But it works and perhaps caching do some magic behind the scene.

This answer helped a lot https://drupal.stackexchange.com/a/269493/1761

// Load the game
$game = \Drupal::entityTypeManager()->getStorage('node')->load($gameID);

$stages = [];

// Get all the stage of the game
$paragraph_field_items = $game->get('field_stages')->referencedEntities();

if (!$paragraph_field_items) {
    throw new \Symfony\Component\HttpKernel\Exception\NotFoundHttpException('This game has no level');
}
    
/** @var \Drupal\paragraphs\Entity\Paragraph $paragraph */
foreach ($paragraph_field_items as $paragraph) {

  // Get the translation
  $paragraph = \Drupal::service('entity.repository')->getTranslationFromContext($paragraph);
    
  $description = [
      '#type' => 'processed_text',
      '#text' => $paragraph->get('field_description')->value,
      '#format' => 'basic_html',
  ];

  $stages [] = [
      'title' => $paragraph->get('field_title')->value,
      'image' => $paragraph->get('field_image'),
      'description' => $description,
      'east_lv95' => $paragraph->get('field_east_lv95')->value,
      'north_lv95' => $paragraph->get('field_north_lv95')->value,
  ];
}

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.