Add a core helper method (or parameter) to get configuration values in a different language

Created on 27 January 2025, 2 days ago

Problem/Motivation

Loading a configuration value in a different language is DX-wise pain.
In many cases you don't have to care for getting the translation of a configuration value, as config_translation simply uses the active language to retrieve the configuration value (implicitly).

But there are cases, where you need to explicitly need to retrieve the config value in a certain language. Typical cases are for example:

  • Sending mails to users in their language (where the mail texts are stored in DB)
  • Administrative cases, where you need to show configuration values different from your own language, for example for translation
  • ...?

For this, Drupal uses the following (not easy to find) pattern:

$original_language = $this->languageManager->getConfigOverrideLanguage();
$this->languageManager->setConfigOverrideLanguage(new Language(['id' => $langcode]));
// GET THE CONFIG VALUE HERE
$this->languageManager->setConfigOverrideLanguage($original_language);

Which changes the config language and resets it, after loading the value from the config.

To find the many use-cases of this pattern in core, simply search for "setConfigOverrideLanguage".

Some examples:

DateFormatter.php:

  /**
   * Loads the given format pattern for the given langcode.
   *
   * @param string $type
   *   The machine name of the date format type which is one of:
   *   - One of the built-in date format types: 'short', 'medium',
   *     'long', 'html_datetime', 'html_date', 'html_time',
   *     'html_yearless_date', 'html_week', 'html_month', 'html_year'.
   *   - The name of a date format type defined by a date format config entity.
   *   - The machine name of an administrator-defined date format type.
   *   - 'custom' for a custom date format type.
   * @param string $langcode
   *   The langcode of the language to use.
   *
   * @return \Drupal\Core\Datetime\DateFormatInterface|null
   *   The configuration entity for the date format in the given language for
   *   non-custom formats, NULL otherwise.
   */
  protected function dateFormat($type, $langcode) {
    if (!isset($this->dateFormats[$type][$langcode])) {
      $original_language = $this->languageManager->getConfigOverrideLanguage();
      $this->languageManager->setConfigOverrideLanguage(new Language(['id' => $langcode]));
      $this->dateFormats[$type][$langcode] = $this->dateFormatStorage->load($type);
      $this->languageManager->setConfigOverrideLanguage($original_language);
    }
    return $this->dateFormats[$type][$langcode];
  }

user.module:

/**
 * Implements hook_mail().
 */
function user_mail($key, &$message, $params) {
  $token_service = \Drupal::token();
  $language_manager = \Drupal::languageManager();
  $langcode = $message['langcode'];
  $variables = ['user' => $params['account']];

  $language = $language_manager->getLanguage($langcode);
  $original_language = $language_manager->getConfigOverrideLanguage();
  $language_manager->setConfigOverrideLanguage($language);
  $mail_config = \Drupal::config('user.mail');

  $token_options = ['langcode' => $langcode, 'callback' => 'user_mail_tokens', 'clear' => TRUE];
  $message['subject'] .= PlainTextOutput::renderFromHtml($token_service->replace($mail_config->get($key . '.subject'), $variables, $token_options));
  $message['body'][] = $token_service->replace($mail_config->get($key . '.body'), $variables, $token_options);

  $language_manager->setConfigOverrideLanguage($original_language);
}

While I think this is a valid pattern and can be helpful in complex cases, it's not very self-explaining and easy to find. What I would have expected would be one of the following:

  • Helper method like ->getTranslated($id)
  • Optional $langcode parameter in the $config->get($id, $langcode = NULL) function

Maybe there are better ideas.

At least this pattern should be documented somewhere, I think? Really wasn't easy to find.
In my case, I needed it here:
https://git.drupalcode.org/project/user_registration_reminder/-/blob/1.x...
for sending mails in user language.

Would be great to discuss!

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

Feature request
Status

Active

Version

11.0 🔥

Component

config_translation.module

Created by

🇩🇪Germany Anybody Porta Westfalica

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Production build 0.71.5 2024