Change record status: 
Project: 
Introduced in branch: 
main
Introduced in version: 
11.5.0
Description: 

In some situations it is necessary to render a fragment in a different language than the one negotiated when the request started. This can be the case during cron runs, when indexing content for search or when sending email with the language of the recipient.

Added Methods

Two new methods have been added to the LanguageManagerInterface:

  /**
   * Temporary enforces the render language.
   *
   * @param \Drupal\Core\Language\LanguageInterface $language
   *   The language to use while rendering.
   * @param string $type
   *   (optional) The language type; e.g., the interface or the content
   *   language. Defaults to
   *   \Drupal\Core\Language\LanguageInterface::TYPE_INTERFACE.
   *
   * @return $this
   */
  public function setRenderOverrideLanguage(?LanguageInterface $language = NULL, $type = LanguageInterface::TYPE_INTERFACE): static;

  /**
   * Returns a temporary enforced render language.
   *
   * @param string $type
   *   (optional) The language type; e.g., the interface or the content
   *   language. Defaults to
   *   \Drupal\Core\Language\LanguageInterface::TYPE_INTERFACE.
   *
   * @return \Drupal\Core\Language\LanguageInterface|null
   *   the current render override language.
   */
  public function getRenderOverrideLanguage($type = LanguageInterface::TYPE_INTERFACE): ?LanguageInterface;

These methods are typically used in combination with RendererInterface::renderInIsolation() or RendererInterface::executeInRenderContext(). Ensure to use a try block and switch to the original language in a finally block in order to avoid leaking the language override when an exception is thrown during rendering.

Example

    $old_language = $this->languageManager->getRenderOverrideLanguage();
    try {
      $this->languageManager->setRenderOverrideLanguage($language);
      $topic = [];

      // Render the title in this language.
      $title_build = [
        'title' => [
          '#type' => '#markup',
          '#markup' => $plugin->getLabel(),
        ],
      ];
      $topic['title'] = $this->renderer->renderInIsolation($title_build);
      $cacheable_metadata = CacheableMetadata::createFromRenderArray($title_build);
      [...]
      $topic['cacheable_metadata'] = $cacheable_metadata;
    }
    finally {
      // Restore the original language.
      $this->languageManager->setRenderOverrideLanguage($old_language);
    }

Deprecations

  • Calling Drupal\language\ConfigurableLanguageManager::__construct() without the $translationManagerClosure argument is deprecated in drupal:11.5.0 and it will be required in drupal:14.0.0.
Impacts: 
Module developers