Configuration language is not adjusted after changing the site default language

Created on 31 January 2023, almost 2 years ago
Updated 7 April 2024, 8 months ago

Problem/Motivation

The switching default language does not account for configuration translations, locale_modules_installed() and \Drupal\locale\LocaleConfigSubscriber.

Steps to reproduce

  1. Install Drupal standard in English
  2. Enable the locale module
  3. Add another language (for example German) on admin/config/regional/language
  4. Change the default language to the one you just added

Changing the default language will not make any changes to configuration. If you export at this point you will have a language/de folder in your configuration sync. If you export before step 4 and then export after you will only see that only system.site and language.negotiation need re-exporting.

If you then install a module (for example jsonapi) massive configuration change will occur. A language/en folder will be created. All default configuration will be changed to 'de' and translated.

Also, if you switch default language back to English, the configuration language for existing config never switches back, not even when you install more modules.

Proposed resolution

Fix up configuration after changing the default language. Say the old default language was 'en' and the new language default language is 'de' - we will need to start a batch that:

  1. Creates a language/en collection and moves the current english strings from the default collection there.
  2. Changes the langcode of all default collection configuration to 'de' - see locale_system_set_config_langcodes()
  3. Merges the translations that are in language/de to the default collection.
  4. Removes the language/de collection

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

🐛 Bug report
Status

Active

Version

11.0 🔥

Component
Language system 

Last updated 1 day ago

  • Maintained by
  • 🇩🇪Germany @sun
Created by

🇬🇧United Kingdom alexpott 🇪🇺🌍

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

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • Issue created by @alexpott
  • 🇮🇷Iran tsotoodeh

    The same issue observed in 9.5.x, it is a core design issue, I opened a multilingual support issue:
    Multilingual support of strings in second language website 🐛 Multilingual support of strings in second language website Closed: duplicate

    I Tried using configuration update manager module to adjust langcode from default language to primary language, time consuming process! Although the content is translated but it would not shown correctly in second language. Same issue here!

  • 🇪🇸Spain Jose Reyero

    Updated task description to account for the fact that when you switch default language back to English, nothing happens, existing config language is never updated.

    I guess we need to make locale_config_batch_set_config_langcodes() behave the same for all languages and not to make an exception if default language is "en", or maybe keep track of the last language set for configuration, and whether the default langcode has been changed or not...

  • 🇮🇷Iran tsotoodeh

    Well, as far as I can see the Drupal multilingual efforts has come a long way from the time that i18n or internationalization and localization modules was once were.
    To be truly multilingual the configuration translation and interface translation should be taken a second thought.

    Updated task description to account for the fact that when you switch default language back to English, nothing happens, existing config language is never updated.

    As you said, the the language switch should be respected both in terms of configuration of the elements of the site and also the contents. An architectural plan should be devised for this task. Currently the configuration in consistency after switching the language from default language are many to account.

  • 🇬🇪Georgia almador

    I don't know if this is the right topic to share my issue, but it's also related to switching the original language.

    What I did - while upgrading Drupal 8 to Drupal 9 by mistake I changed my default language from English to Spanish. When I realized this (after the upgrade) I switched my default language back to English from this page:
    admin/config/regional/language

    But now, when I'm trying to edit any of my translations related things it still says "Español (original)".

    Is there any way to switch every translation option back to English (original)?

  • 🇭🇺Hungary Gábor Hojtsy Hungary

    Made the title more specific.

  • 🇭🇺Hungary Gábor Hojtsy Hungary

    Looking at why this happens. When a module is installed after the default language is changed:

    • locale_modules_installed() is called (this is a hook that responds to modules being installed).
    • This calls locale_system_update() which sets up a batch.
    • The batch first runs translation updates (downloads .po files from localize.drupal.org and imports them). This is not relevant for this bug.
    • Then it adds a sub-batch with locale_config_batch_update_components() passing the request to update default langcodes in config. Because there are no specific components requested, this will get a list of all the default config objects (config items that are shipped with installed extensions). See https://api.drupal.org/api/drupal/core%21modules%21locale%21src%21Locale...
    • Then it invokes locale_config_batch_build() which uses this component list of all default config and adds two kinds of operations: (1) to update the langcode of them and (2) to update the translations of them.
    • The batch operation locale_config_batch_set_config_langcodes() just wraps updateDefaultConfigLangcodes(). This operates if the site default langcode is not English and updates all of the active copies of default config that do have an English langcode or are missing a langcode to the current site default langcode. This does not change existing active config if it is already some other language. It also does not change the active config back to English if the new default is English. It just does not operate in that scenario.
    • Then a batch operation is added for 20 config names each of locale_config_batch_refresh_name(). This wraps updateConfigTranslations(). This considers the active config language and detects if the translation should be stored within the active config object or an override. This is independent of the site default language and only considers the langcode of the active config object.

    All in all I think the logic protects the existing language changes in active config if they were made prior to the default language change. So if you already have a Swedish site let's say, you switch to Finnish, the active config items that were previously Swedish will remain Swedish. Newly installed modules will get their config in Finnish in active config, so you end up with a mix of config items with Swedish and Finnish. But the integrity of your config is maintained.

    Now as to what happens when default language is changed, I'll post another comment, this is already quite long :D

  • 🇭🇺Hungary Gábor Hojtsy Hungary

    Default language change on the UI is implemented in LanguageListBuilder::submitForm(), and does this essentially:

       // Save the default language if changed.
        $new_id = $form_state->getValue('site_default_language');
        if ($new_id != $this->languageManager->getDefaultLanguage()->getId()) {
          $this->configFactory->getEditable('system.site')->set('default_langcode', $new_id)->save();
          $this->languageManager->reset();
        }
    
        if ($this->languageManager instanceof ConfigurableLanguageManagerInterface) {
          $this->languageManager->updateLockedLanguageWeights();
        }
    

    Language module reacts on the config save of the default langcode in its ConfigSubscriber but that of course is not related to interface translation.

    Finally locale has its own LocaleConfigSubscriber but that does not consider a default language code change as something to care about.

  • 🇭🇺Hungary Gábor Hojtsy Hungary

    I'm a bit torn as to how to resolve this. For one, we want to make default language changing as easy as possible. The intent of the code is to consider config similar to content, where the existing language and overrides of configs is kept, except in the English special case that it assumes belongs to the default config that needs changing. There is no such logic for content entities either to swap their default language and translations when a site default language changes.

    At the same time, users likely expect to edit configuration in the site's default language by default, which the current logic attempts to ensure, at least as long as that default is English and after the first transition from English to non-English. It does not maintain that user experience once you want to make the second language transition, whether back to English or to something else. It does leave your config intact but it does not maintain the assumed user experience. Also, if the first language transition happens later in the site's life, a massive config change happens then. That in itself is expected, but not when you install a new module :D So the problems are:

    • When you change the site default language, the current logic is not run. That would probably be "easy" to fix by launching the existing batch then, since it deals with all default config. Not sure how to make it happen in a config import though?
    • After you change the site default language AGAIN, the current logic keeps your config as-is (not English) and new config is now created in the new default language. To maintain the idea that your active config is in the site default by default, we would need the logic explained in the issue summary to extract the translations from active config, create the overrides and save the active config with the proper values fom the overrides in the new default (and remove the new default's overrides for default config).
  • It seems that someone has been changing some things in how languages work.

    I am now unable to rename a certain language (D 10.2.4).
    I wanted to name English en and German de.
    The YML configuration is correct, but when the page is shown in the default original language German, it will just say "Deutsch" no matter what.
    I guess the new code changes fail to retrieve and display the correct label.

  • Actually I had it working correctly on a site where I did the following :

    Installed the site in English

    Added German
    Added British English
    Deleted English

    works.

  • there is actually more to this issue.

    languages need a translatable label, which would resolve the present issue and a dozen more related issues I have found today when going down this rabbit hole.

    BUT
    languages also need editable labels that will be displayed in translations, verbose translations and abbreviated translations, URLs ...

    So for example, a site could have installed British English and it would display the following way :
    "en-gb" (non translatable) in any technical-related stuff such as hreflang, html, etc.
    "British English" (translatable) in any configuration dialog in the admin interface, translation forms, etc.
    "en" (translatable) as a label for language switcher links
    and potentially, the site owner would want something else (translatable) to be displayed in the URL, such as /eng/ or /english/ or ... whatever

    so the short ISO language code would be used by Drupal to identify the language and source translations, and would be untranslatable.
    and then there should be 3 translatable labels on top.

  • I can now also confirm the workaround to correct this issue on running sites.

    First, install an additional language.
    Then change the language of all localized content to that new language you just installed.
    That may be nodes, blocks, media, redirects and URLs, etc.

    Then delete the language of which you can't change the name (be careful, this will delete all content you forgot to switch to the new language).

    Purge the cache and then re-install the language you just deleted.

    Edit the name of that language to what you wanted and then change the contents' language back to what it was.

    So it seems like something screws up the language settings when installing the site or when declaring a language default.

  • never mind the workaround, one of the language labels reverted back to original after doing something else on the site.

Production build 0.71.5 2024