1

I have defined a route as follow:

mymodule.node_summary:
  path: '/node/{node}/summary'
  options:
    parameters:
      node:
        type: 'entity:node'
  defaults:
    _controller: '\Drupal\mymodule\Controller\NodeSummaryController::content'
    _title: 'Summary'
  requirements:
    node: \d+
    _entity_access: 'node.view'

Then I have created the following controller:

class NodeSummaryController {

  public function content(Node $node = NULL) {
    $view_builder = Drupal::entityTypeManager()
      ->getViewBuilder('node');
    $summary = $view_builder->view($node, 'summary');
    $render = Drupal::service('renderer')
      ->renderPlain($summary);
    $response = new Response($render);
    return $response;
  }
}

If I visit the page /nl/node/xxx/summary everything is fine, my node's summary is displayed in dutch

But if I try to get this content with a sub-request, I get the result in the default language of my site, not in dutch

  $kernel = \Drupal::service('http_kernel.basic');
  $sub_request = \Symfony\Component\HttpFoundation\Request::create("/nl/node/xxx/summary");
  $response = $kernel->handle($sub_request, \Symfony\Component\HttpKernel\HttpKernelInterface::SUB_REQUEST);
  $html = $response->getContent();
  dpm($html); // ERROR THIS IS NOT IN DUTCH
2
  • How is language negotiation handled on your site? Is it either URL or language prefix? If so, you'll need to pass the path/URL for that language, to get content in that language.
    – Jaypan
    Mar 8 at 14:49
  • This is URL: Language from the URL (Path prefix or domain). As you can see in $sub_request = \Symfony\Component\HttpFoundation\Request::create("/nl/node/xxx/summary"); I am passing the language code. Note that visiting this url give me to good language. Only the subrequest failed
    – Baud
    Mar 8 at 14:57

1 Answer 1

2

I was a bit overly optimistic in the previous question suggesting a sub-request. The language manager service doesn't store data in such a way that it can run within a sub-request scope. So it seems you need to do the same as in the previous question, only that now the interface translation works without a custom negotiator by resetting the language manager (and also the string translation service, see the comment) before running the sub-request:

$language_manager = \Drupal::languageManager();

$langcode = 'nl';
$language = $language_manager->getLanguage($langcode);
$original_language = $language_manager->getConfigOverrideLanguage();
$language_manager->reset();
\Drupal::service('string_translation')->setDefaultLangcode($langcode);
$language_manager->setConfigOverrideLanguage($language);
\Drupal::service('entity_field.manager')->clearCachedFieldDefinitions();

$kernel = \Drupal::service('http_kernel.basic');
$sub_request = \Symfony\Component\HttpFoundation\Request::create('/' . $langcode . '/node/1/summary');
$response = $kernel->handle($sub_request, \Symfony\Component\HttpKernel\HttpKernelInterface::SUB_REQUEST);

$language_manager->reset();
$current_language = $language_manager->getCurrentLanguage();
\Drupal::service('string_translation')->setDefaultLangcode($current_language->getId());
$language_manager->setConfigOverrideLanguage($original_language);
\Drupal::service('entity_field.manager')->clearCachedFieldDefinitions();

$html = $response->getContent(); 
5
  • Many thanks for your help! This is working except for the computed fields...like the other question : drupal.stackexchange.com/a/314993/61398 I will create manually the text like the ones produced by this controller. I'm giving up
    – Baud
    Mar 8 at 17:36
  • I've found some time to debug, the reason t() doesn't work is a core issue that the service string_translation is initialized once with the language of the main request and not updated when a different language is negotiated. I've added another workaround to the code. I think now it's really translating everything of the rendered node.
    – 4uk4
    Mar 10 at 9:05
  • Wonderful it is now translating the computed fields as well! Many thanks for your hard work. Don't you think I should add a bug/new feature in the Drupal queue to cache the fields definitions by language? [If this is the original problem... ]
    – Baud
    Mar 10 at 10:18
  • We solved this already in the previous question. This topic here is more general, to translate everything in the sub-request, translated strings in code, config, or content. Your computed fields are code, the other fields config. A lot of core issues need to be solved. To start with, why is the current language stored in string translation. They just could get it from the language manager with the same efficiency, this service has a static cache as well. The same is for config. When all depends on the language manager it needs to get a stacked storage to store per request.
    – 4uk4
    Mar 10 at 10:38
  • ok... it is a little bit over my head... Anyway it is working nicely.
    – Baud
    Mar 10 at 11:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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