Score:0

Sub request doesn't take care of the language

sa flag

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
Jaypan avatar
de flag
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.
Baud avatar
sa flag
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
Score:1
cn flag

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(); 
Baud avatar
sa flag
Many thanks for your help! This is working except for the computed fields...like the other question : https://drupal.stackexchange.com/a/314993/61398 I will create manually the text like the ones produced by this controller. I'm giving up
4uk4 avatar
cn flag
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.
Baud avatar
sa flag
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... ]
4uk4 avatar
cn flag
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.
Baud avatar
sa flag
ok... it is a little bit over my head... Anyway it is working nicely.
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.