Problem/Motivation

I was having a weird problem in a WebTestBase test that I am using to generate screenshots in Hungarian for the translation of the User Guide, and I traced it down to a weird bug that is either a problem in Drupal Core or localize.drupal.org, or some combination.

I was able to reproduce this bug on simplytest.me with the following steps:

a) Install Drupal Core 8.2.0-rc2 in English, with the Standard profile. Make sure that you check the "Check for updates" box, so that the Update Manager module is installed.

Note: In comment #17, this was retested in Drupal 8.6.x as of April 30, 2018, and it is still a bug.

b) Install the 4 multilingual modules from admin/modules.

c) Go to admin/config/regional/language and add Hungarian. Translations are imported from localize.drupal.org. Hungarian is 99% translated today in RC2 -- there are only 2 untranslated strings.

d) Set Hungarian as default language and delete English. (Note: this is interesting to try to do when you do not read Hungarian! Quite an adventure. Luckily, I am "slightly familiar" with the Drupal admin UI and URLs. :) ) At this point, you can verify that the Toolbar across the top of the screen is fully in Hungarian. In particular, the left-most link from the Manage menu (Content in English) says "Tartalom".

e) Go to admin/modules and install the core Activity Tracker module. Translations are imported. Note: I have no idea why translations would be imported at this time, since weren't they already imported for Core? But they are definitely being imported... I can see this in my test as well.

f) Go to admin/config/regional/translate and search for the word "Content". You will see that its translation has become "Content" (English) instead of "Tartalom". Content type is also screwed up, but some other words are still translated... Screenshot:

Translate UI page showing English instead of Hungarian

In my tests, after this point the Toolbar in screenshots is sprinkled with English words amongst the Hungarian. The words "Help" and "People" and "Content" are in English, while the rest is still in Hungarian. But the root cause appears to be that some translations are being overwritten.

I have no idea what the root cause of this happening is... and I think I have a way to work around it for my screenshots (on admin/config/regional/translate/settings I should be able to set it so imports do not overwrite existing translations. Hopefully.) Also note that in my tests I have verified just before installing this module that the word Content is translated to Tartalom and just after it is Content, so I am quite sure it is the translation import from this module install that is causing the problem.

Proposed resolution

1. Figure out why:

a) Translations are being imported when installing a Core module even though Core translations have already been imported when I added the language.

b) When they are imported, they are overwriting some words with English instead of Hungarian.

The problem occurs because the locale_modules_installed() sets the langcode of installed config before the installed config has been translated. This means that the \Drupal\locale\LocaleConfigSubscriber creates translations into the site's default language using the english in the content.

2. Fix the problem(s) by not setting the config's langcode in locale_modules_installed(). Set it as part of translating the configuration in the locale batch that runs after configuration has installed. This results in the system not saving incorrect translations and configuration being correctly translated.

Remaining tasks

Make a patch with a test.

User interface changes

UI translations will not be overwritten when installing a Core module.

API changes

  • Add new method LocaleConfigManager::updateDefaultConfigLangcodes()
  • Add new argument $update_default_config_langcodes to locale_config_batch_build() and locale_config_batch_update_components()
  • New batch callback locale_config_batch_set_config_langcodes()

Data model changes

None

Issue fork drupal-2806009

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

jhodgdon created an issue. See original summary.

jhodgdon’s picture

One more note. In my test environment, I set the setting that says "Do not ever overwrite any translations when importing". This bug still occurred -- it had no effect. I guess I will just tell it not to import from the localize server at all (only use local files) after I have initially done so for the Hungarian (or whatever) language.

jhodgdon’s picture

Second note: I have now told Drupal (a) never to overwrite translations and (b) to only use local files.

The UI on admin/config/regional/translate/settings says that it should only now be importing translations from (public files)/translations. There is nothing there in my test environment -- I am archiving the entire public files directory before the test ends (for other reasons).

But it *still* is overwriting my translations, and it is still going through some kind of a batch process when I install the Activity Tracker module in my test. Before the install of this module, the term "Content" is translated, and afterwards, it isn't.

Do these settings do anything at all? How can I get around this bug? Very frustrating...

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

sutharsan’s picture

This bug can still be reproduced with the latest 8.5.x.

e) Go to admin/modules and install the core Activity Tracker module. Translations are imported.

This is the configuration translation batch process, that runs. Not the interface translation batch.

After step "e", I confirmed the translations in locales_target table are actually updated to English. Noteworthy is that the translation is now flagged as a custom translation, while before step "e" it was a normal translation (locales_target.customized = 0).

jhodgdon’s picture

Version: 8.4.x-dev » 8.5.x-dev

Thanks for looking at this again! That is very useful information about what might be happening, in #6.

sutharsan’s picture

Using a debugger I found:
- Where the translation override is written to the database: \Drupal\locale\StringDatabaseStorage::dbStringUpdate
- Where the translation is build: \Drupal\locale\LocaleConfigSubscriber::saveCustomizedTranslation

In \Drupal\locale\LocaleConfigSubscriber::onConfigSave the $config->data has the right langcode (hu) but the translatable configuration still has the same value (English strings) as the $config->originalData.

Further up the call stack, in locale_system_set_config_langcodes() it is written:

  // Need to rewrite some default configuration language codes if the default
  // site language is not English.

This is exactly what happens... it only changes the langcode, but does not change the translatable strings to match the langcode. Not sure if it is correct that the configuration still is in English.

sutharsan’s picture

Status: Active » Closed (duplicate)

If I omit step 'd' and keep English the default language, I can not reproduce the problem. If I keep English but change the default language to Hungarian, I can reproduce.

This issue is a duplicate of #2905295: Configuration language being overwritten during module install.

jhodgdon’s picture

Ah. Well you could say that other one (filed later) was a duplicate of this issue. :) But that one has more action. So, closing this one as a duplicate is correct.

jhodgdon’s picture

Priority: Major » Critical
Status: Closed (duplicate) » Needs review
StatusFileSize
new3.02 KB

I realized today that the other issue is about config translations, not UI translations, if you read the summary. So this issue is different and I'm reopening it. Also, there is a test-only patch from the other issue that actually illustrates this issue, so moving that over here.

Also this issue is critical because data is lost.

This is from @geertvd

jhodgdon’s picture

Status: Needs review » Active

There is no code patch yet.

berdir’s picture

> I realized today that the other issue is about config translations, not UI translations

config and UI translations are actually partially synchronized behind the scenes. As commented over there, this too might be a part/related to the issue I referenced there #2910353: Prevent saving config entities when configuration overrides are applied

jhodgdon’s picture

Yes, they are synchronized behind the scenes. And maybe the cause is the same. But there are two distinct database things happening when you install a module with a non-English default site language:

a) This issue: the UI translations stored in the locale tables are overwritten with English words instead of your language.

b) The other issue: the base config items stored in the config table gets a langcode=your language field added to it, although the text is in English. This doesn't affect the locale collectiion items that are also stored in the same table (which store the config overrides for the translated config) -- those are still there and are unchanged.

Somehow, I do not think that the cause is the same, although it's possible.

catch’s picture

Status: Active » Needs work

The test passes - does that mean the test is incomplete or that the bug was fixed in the meantime?

jhodgdon’s picture

Issue summary: View changes
Issue tags: +Needs tests
StatusFileSize
new34.62 KB
new42.88 KB
new34.88 KB

Good question!

simplytest.me is not working with D8 currently (I checked and there is an issue, apparently being worked on, hooray!), so I just tested this on my local dev machine using the steps in the issue summary (mostly):

a) I started by downloading the 8.6.x dev snapshot from https://www.drupal.org/project/drupal/releases/8.6.x-dev and installing using Standard profile in English.

b) Installed the 4 multilingual modules.

c) Added Spanish (because I can actually read Spanish, unlike Hungarian :) ), and waited for translations batch import. There was an error in the batch process, and I got a weird error message saying:

Error importing translation files
Please continue to the error page

An AJAX HTTP error occurred.
HTTP Result Code: 200
Debugging information follows.
Path: /~d8tmp/batch?id=2&op=do_nojs&op=do
StatusText: OK
ResponseText: 
Drupal already installed | Drupal
...
Drupal already installed
To start over, you must empty your existing database and copy default.settings.php over settings.php.
To upgrade an existing installation, proceed to the update script.
View your existing site.

Here is a screen shot:
Screen shot of error in importing page
There is absolutely nothing in my dblog at this time.

Anyway, it seems like it still imported some of the translations... not too many though. Anyway, moving on...

d) I set Spanish to the default and deleted English. The toolbar's left spot (Content in English) says "Contenido". And I took a screenshot of the UI Translate screen (admin/config/regional/translate) before proceeding to the last step.
Screenshot of admin/config/regional/translate before installing a new module

e) Went to admin/modules and installed the Activity Tracker module. A batch titled "Updating configuration translations" ran. Some of my UI translations on (admin/config/regional/translate were overwritten -- here's a screenshot:

Screenshot of admin/config/regional/translate after installing a new module

So, yes, it is still a bug. I guess the test is not correct.

lokapujya’s picture

Look in setup(). That test currently gets skipped.

jhodgdon’s picture

Um, I don't see that in the patch. Can we make a test-only patch that illustrates the bug, runs, and fails then?

lokapujya’s picture

Not, in the patch, in HEAD:

<?php
class LocaleConfigTranslationImportTest extends BrowserTestBase {

  protected function setUp() {
    parent::setUp();

    // @todo Re-enable the test and only skip it when the translation cannot be
    //   downloaded, or provide a translation as a fixture instead. See
    //   https://www.drupal.org/project/drupal/issues/2828143.
    $this->markTestSkipped();
  }
?>

From my understanding these tests don't run on D.O right now. It seems like the test should work, unless that string just happens to be one that doesn't get over-written.

lokapujya’s picture

Version: 8.5.x-dev » 8.6.x-dev
Status: Needs work » Needs review
StatusFileSize
new9.01 KB

Status: Needs review » Needs work

The last submitted patch, 21: 2806009-21-test-only.patch, failed testing. View results

jhodgdon’s picture

Status: Needs work » Active
Issue tags: -Needs tests

Wonderful, thanks! I looked at the test output and it looks like it is failing in exactly the way we expect, and I looked at the patch and it does look like it's reproducing more or less the Steps to Reproduce in this issue. So, I think we have a good test. I'm not sure about all of those unrelated changes in the test code, but I'm assuming they're coming from the other issue whose patch was merged.

Anyway, I'm removing the Needs Tests tag, because we have a valid test. Now all we need to do is figure out how to fix the actual problem. Accordingly, setting status to Active because we have no patch for the actual problem.

catch’s picture

Status: Active » Needs work

Sorry this should still be 'needs work', because the test-only patch is a valid part of the overall fix for this issue. i.e. there's a patch, and it needs work.

lokapujya’s picture

Now that #2828143: Stop tests like LocaleConfigTranslationImportTest from failing if l.d.o becomes unavailable was committed, the test-only patch in comment #12 is working.

jhodgdon’s picture

RE #25... By "working" do you mean "failing as expected"?

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

aleksip’s picture

Wondering about the title as I find this happening every time I install any module (core or contrib) that contains translatable configuration.

My setups are different from the summary steps a-c though, as I usually install sites in Finnish.

jhodgdon’s picture

If you are having problems with *configuration* being overwritten, it might be #2905295: Configuration language being overwritten during module install instead of this issue. This one is about *translations* in the translation database being overwritten. Both are bad, and both happen when you install a module.

aleksip’s picture

Actually I'm finding that both things happen when I install a new (core or contrib) module with default configuration: translations in both the translation database and configuration are overwritten. This seems to be limited to the translatable strings in the new config.

Has it been verified that this issue is only about *core* modules? With "Core module" so prominently in the title I think it could distract some people from paying more attention to this almost three years old critical issue causing data loss.

mpp’s picture

We have Behat tests that fail on field labels whenever a new module is installed.

The test checks on /node/add/event if there's a Dutch title (Titel). It's always green unless if you just enabled a module then Behat fails and no longer finds "Titel" but it sees the label in the default language of the website (English) "Title".

Our default language is English (but default negotiator is set to Dutch) so either the description in this issue is wrong or it is indeed this issue: https://www.drupal.org/project/drupal/issues/2905295

jhodgdon’s picture

Title: Installing a Core module causes translations to be overwritten » Installing a module causes translations to be overwritten

Good point, removing "core" from the issue title. And yes this issue is still valid and still needs to be fixed.

I still think these are two separate issues. This issue is about strings in the translation database being overwritten. The other issue #2905295: Configuration language being overwritten during module install is about configuration items being overwritten. They have similar effects on the site, but not (I think) the same cause. Both of them are critical, 2-3 years old, and need to be fixed.

aleksip’s picture

Great! Let's hope that this small change in the title gets some more eyeballs on this issue.

berdir’s picture

Status: Needs work » Needs review
StatusFileSize
new4.42 KB

> They have similar effects on the site, but not (I think) the same cause.

Actually, they basically do have the same cause, in that the behavior described in the other issue is the direct cause of this.

The interface texts and config translation texts are tightly linked and are synced in both directions if either changes. The reason for that is that localize.drupal.org can only do interface translations, so we basically treat all config translations, just identified by their source string, as interface translation. Kind of eludes me why we then even have config translations in the first place and don't just put everything through t() :p

So what's happening here is that we have two things that are in combination causing this behavior:

a) locale_system_set_config_langcodes() updates all default config to the current active language. Strangely enough, this isn't called when the default language *changes* but only when a module or theme is installed. That's why we have this delayed effect.

b) Then, that saves all config on the system and \Drupal\locale\LocaleConfigSubscriber::onConfigSave() then listens on that and updates the locale table, thinking that all the strings that are in the config, which were just changed from "en" to "somethingelse" are now magically translations for "somethingelse".

=> Boom, now all your translations are messed up.

I think the whole constant sync between interface and config translation is pretty flawed and has many problems but especially listening to the default configuration and assuming that's content for the langcode that currently happens to be set in the file definitely seems wrong.

This test is easily fixed by just removing that specific event listener, lets see if any tests except it to do something and what. This was apparently added in #2212069: Non-English Drupal sites get default configuration in English, edited in English, originals not actually used if translated, the problem is that it was based on a completely different architecture, that we changed since then.

Note that this issue isn't about changing EN configuration, that's yet another problem, that I'll create a separate issue and patch for.

gábor hojtsy’s picture

The interface texts and config translation texts are tightly linked and are synced in both directions if either changes. The reason for that is that localize.drupal.org can only do interface translations, so we basically treat all config translations, just identified by their source string, as interface translation. Kind of eludes me why we then even have config translations in the first place and don't just put everything through t() :p

Most of Drupal is now configuration. Your content types, forms, views, blocks, etc. If we would not be able to translate them on localize.drupal.org, then downloading a "Drupal translation" would mean most of Drupal would not be translated. Also a site that was installed before translations were done would never get the benefit of updated translations for anything in config. So I think we need that feature, but it could be more resilient.

The config strings are not just identified based on their source strings, config schema and default shipped config is at play.

1. Only config that has a shipped config counterpart would ever participate in localization update. Others should be left alone and not affected by these problems(?)
2. Only the keys of config that are present in that shipped config and are designated as translatable keys in the corresponding config schema would participate in this process and not any other items.
3. After (1) and (2) indeed the string (and any associated context from the config schema) would be used to look up translations.
4. If the active config has a different string from the shipped config then the translation relation is broken and translation updates should not happen anymore either.

Theoretically 1, 2 and 4 ensure that only config keys that are translatable in only the config that was shipped, and only in the case the shipped string is still intact in live config would the string participate in translation updates.

Is there a problem with this logic or does the code not follow that logic?

Status: Needs review » Needs work

The last submitted patch, 35: 2806009-35.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

berdir’s picture

Status: Needs work » Needs review
StatusFileSize
new4.08 KB

Sorry about the t() comment, I'm aware it is a bit more complicated than that although I didn't see/forget about some of the existing checks that we already have. I do still think that the current sync is problematic in many ways though, there's a reason we have critical issues like this one open for years :)

Going back a step, I've basically converted the larger browser test into a minimal new test method on LocaleConfigSubscriberForeignTest that might make it easier to talk about this. What happens is that we have a translation for language HU, then we resave the HU config file that contains a string that's still EN, then the system treats that as a new translation for HU and force-updates it.

What I missed before is that we already have a lot of checks in \Drupal\locale\LocaleConfigSubscriber::saveCustomizedTranslation to decide when we shouldn't update, and basically, there are two cases:

a) No existing translation and the string in the active config is not the same as the shipped config. That kind of makes sense, and prevents the scenario above because then "Test" would be identical to the shipped version and would not be added as a *new* translation.
b) But the second case is that if there is an existing translation and it's different, then we update it. And this is basically the culprit. If we'd remove this, then it wouldn't happen anymore.

Gabor tried to explain me the use cases for why this is working as it should but honestly, I still don't really understand them. Based on the test fails, we only have specific assertions on the exact behavior in this class, which are failing now, but we don't have any explicit tests as to why we are doing this. It would be helpful to see a specific use case when this is necessary, just as written steps would be a good start, I can try to find some time to create a test from it.

Status: Needs review » Needs work

The last submitted patch, 38: 2806009-more-tests-38.patch, failed testing. View results

berdir’s picture

Note: I think most of the examples reported here, for example #32 from @mpp is actually this problem: #3079242: \Drupal\locale\LocaleConfigManager::updateConfigTranslations() should not remove non-existing EN translations, which now has a hopefully much less controversial/complex fix. Please test and report over there.

Edit: Also, the reason that my new test method above didn't fail is most likely also #3079330: LocaleConfigSubscriberTest has many assertions that don't run, that test really isn't testing much right now.

gábor hojtsy’s picture

b) But the second case is that if there is an existing translation and it's different, then we update it. And this is basically the culprit. If we'd remove this, then it wouldn't happen anymore.

Well, the idea is that when you enter something in locale, then we update the config files, when you import config, then we update locale. So they are in sync. When its different, we need to update it or it will get updated silently later when a translation update happens or something else. The question is why is it different if you did not intend it to be different?

Pure config translation files would only ever contain translation strings, so whatever we find there we should consider as valid translation. For active config that is not in the English shipped language state anymore, that has keys that are possibly untranslated. So long as they are exactly as in the shipped config I believe we assume they are not translated and we don't save the equal English text as the translation of English in that language. But as soon as it starts being a different string, we need to assume it is a translation, no?

Where exactly is does our logic fail here?

jhodgdon’s picture

OK.... let's think again.

So, I have a site whose sole language is Spanish. I created this site by installing in English, then adding Spanish language (and importing translations from localize.drupal.org), setting Spanish to default, and then deleting English.

So then I install a Core module. Whenever you install a module, the config/locale sync process happens. From comment #35 (Berdir):

a) locale_system_set_config_langcodes() updates all default config to the current active language. Strangely enough, this isn't called when the default language *changes* but only when a module or theme is installed. That's why we have this delayed effect.

b) Then, that saves all config on the system and \Drupal\locale\LocaleConfigSubscriber::onConfigSave() then listens on that and updates the locale table, thinking that all the strings that are in the config, which were just changed from "en" to "somethingelse" are now magically translations for "somethingelse".

[Note: It does look like locale_system_set_config_langcodes() is only called from locale_modules_installed() and locale_themes_installed()]

So it looks like the real problem is that when I install in English, add Spanish, set Spanish to default, and then delete English, the config is not updated in that process. So at that moment (before I install another Core module), all of my config is still in English, and the site is working correctly because the translations are in the locale table, so that if I load a config item to use it in the site, it gets translated into Spanish.

But that config/locale sync process is assuming that if my site is in Spanish, then all the translatable text in the config that is in my database is in Spanish. That assumption is incorrect, so when we call locale_system_set_config_langcodes(), it goes through and changes the langcodes of all the config in my database from EN to ES, even though the actual translatable text is still in English. And then onConfigSave() thinks that text is Spanish and saves it in the locale database as translations, overwriting the translations in my database.

So... Why does the config/locale sync process think that if my site is in Spanish, all the translatable text in the config is already in Spanish? What would have normally happened to make that happen, that doesn't happen if I start with an English site, add Spanish, set Spanish default, and delete English? I think that is the real question here, isn't it?

gábor hojtsy’s picture

But that config/locale sync process is assuming that if my site is in Spanish, then all the translatable text in the config that is in my database is in Spanish.

No. It assumes that active config copies of shipped config would either be in English or in your foreign site default language. It does not care for all the translatable text in the config that is in my config database it only cares for active config instances of config that was also shipped config. Locale does assume all of those are in the site default language (English or otherwise).

The idea is if you have a French site, then you don't want your base config to be Spanish and then translate to French from there. You have a primarily French site. So when you go edit a view, you want to edit the French view. If you want to edit Spanish, you would go edit the Spanish translation. Same goes if you replace Spanish with English in the prior sentences.

Locale does not care for and should not touch translations or active config of things that did not use to be default config. It does not make assumptions about those.

So it looks like the real problem is that when I install in English, add Spanish, set Spanish to default, and then delete English, the config is not updated in that process.

Yeah if we want to continue with Locale's assumption, looks like it would need to piece apart your active config. If English is enabled for translation, it could identify English translations and save them to a translation override. If not then those customisations will get lost. Then rewrite your default config as Spanish (with the actual Spanish translation merged). Then continuing on everything will be as expected by Drupal and you would edit your config as Spanish (ie. Spanish content types, field labels, views, etc). When English gets deleted then, if it was enabled for translation, the customisations would get lost, but you asked for it.

jhodgdon’s picture

Hm. So... The bottom line is that when I install in English, add Spanish, delete English (without editing any config), the site is fine. All of the shipped config is there in English, and it is translated into Spanish when the site pages are being displayed.

But then when I install a new module, everything is broken. The reason it is broken is this locale_system_set_config_langcodes() function that reads in all the config and just changes the language codes from EN to ES, but leaving the text as it was (still in English). Then to further complicate things, that English text is getting saved to the translation database as Spanish translations. So a lot of UI text, whether from config or from form/render elements that happens to have the same text as some config (like the word t('Content')), is now in English.

I think this would happen even if I installed in English, added Spanish, and set it to be the default language.

I guess I still don't understand why we have locale_system_set_config_langcodes()... It seems like if I have some config from somewhere whose language is English, and I edit it in the UI, then maybe I should set the langcode to be the site's default langcode. But going through and settting all config, with the text that was there, to think it's in the default langcode... why would this ever be a good idea?

berdir’s picture

> Pure config translation files would only ever contain translation strings, so whatever we find there we should consider as valid translation.

Not much time right now, but you mostly talk about the config translations/overrides I think. But this issue is specifically about the active configuration. So again, changing the default configuration would mean it's not possible to change it with locale afterwards anyway?

> Yeah if we want to continue with Locale's assumption, looks like it would need to piece apart your active config. I

Yes, but I think that actually belongs in the related issue #2905295: Configuration language being overwritten during module install, if we do that over there, then we can clean up some of the mess, but unless you assume that the configuration of a site will be translated 100%, you still run into the problem that we have here.

jhodgdon’s picture

Hm.... So.... If the config was partially translated into Spanish (assuming that's the default language), and you acquired Spanish text and saved that along with the Spanish language code into the config, you'd be OK, because you wouldn't be overwriting translations that weren't there before. For example, if the word "Content" was translated via Locale, you would read the translation "Contenido" from the Locale table and put it into the config, and then in this process you would be saving that "Contenido" back into the Locale database as a translation, no data loss. And if the word "Foobar" (in the config) wasn't translated, the worst you would be doing is adding "Foobar" with translation "Foobar" into the locale table, which wouldn't write over an existing translation of "Foobar".

So I don't think it's a problem if some of the config isn't fully translated, as long as you read the translations and put them into the config before you save the config with the new langcode?

gábor hojtsy’s picture

@jhodgdon:

I guess I still don't understand why we have locale_system_set_config_langcodes()... It seems like if I have some config from somewhere whose language is English, and I edit it in the UI, then maybe I should set the langcode to be the site's default langcode. But going through and settting all config, with the text that was there, to think it's in the default langcode... why would this ever be a good idea?

The whole process is supposed to serve this scenario:

1. You have a foreign language site, let's say Chinese.
2. You install modules, they have config shipped in English of course.
3. Your site is Chinese, so you want your config to be Chinese (ie. when you go edit content types, views, etc, you don't want to edit them in Chinese even though modules shipped in ChineseEnglish and you may still even have English on your website as a language).
4. So locale overwrites the langcode of the active config of shipped configs to be Chinese to conform to this assumption about what the user expects.
5. Then locale proceeds to manage the translations of the config / locale to be in sync.

As part of (5) locale then needs to deal with applying locale translations to active config, where only the langcode of the config was changes initially. So it absolutely needs to work with active config that is partially translated. Rather than saving equal translations to the DB, it checks if the value in active config is different from the value in default config (for the same translatable keys) and will only save translations where there was a difference. It assumes the difference is because it got translated. What this means is locale deals with these incomplete translated files, and then it can even update their translations later on as more complete translations are downloaded and imported from localize.drupal.org, it can then sync translation updates into your active config, so your field labels, views, etc. get more and more Chinese. When you edit your config it saves back to locale, and you can configure locale to protect local translation modifications, in which case remote translation updates will also not overwrite your local modifications even to these Chinese configs.

So this is the feature set and user assumptions we are dealing with here. There are apparently bugs with how its implemented though :)

mpp’s picture

Happy to see this issue is getting some (needed) traction.

Note: I think most of the examples reported here, for example #32 from @mpp is actually this problem: #3079242: \Drupal\locale\LocaleConfigManager::updateConfigTranslations() should not remove non-existing EN translations, which now has a hopefully much less controversial/complex fix. Please test and report over there.

@Berdir, we have English enabled as the default language and the issue arises when new modules are enabled.

@gabor posted the following remark on another issue:

If you run a monolingual site and install in that language, that language will be shown in the overview and that language will be editable.

=> @gabor, I'm assuming that in this case one has Chinese config in his /config/sync folder?

We run a lot of "monolingual" (i.e. Dutch) websites but none of theme are truly monolingual because that would imply that we have all our config in Dutch.

From a code perspective we always want to have the English configuration labels in /config/sync.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

kristiaanvandeneynde’s picture

Piling on #48: We also have the default language set to DE or NL, but need the contents of config/sync to be EN. The reason is simple: All modules ship with EN config, so if we wanted our config/sync folder to be DE or NL, then all modules would not be able to drop their config in config/sync unless it would be in the wrong language for that folder.

kristiaanvandeneynde’s picture

Having read up on the entire issue, I strongly disagree with the logic presented in #47.

  1. We require all modules to ship with English config, including core itself.
  2. This means that whenever you install a module, you get the English version of the configuration.

To me it makes a lot more sense to simply always sync the original (installed) config to the active configuration storage and leave it as such and then when importing or adding translations, store those in the config/sync/LANGCODE folder. Not doing so really messes with the development flow of multilingual websites.

Look at it from an international agency's perspective as it is now:

  1. Several developers work on a German client's project in English, many of whom do not speak German
  2. When it's almost time to go live, we change the site's default language to DE, but keep EN enabled for our international developers
  3. We install a new module, run a config-export and boom, 500+ files have suddenly changed language. Good luck finding just the changes you intended to commit to your feature branch. Also, unless you mass commit this new noise and change your entire config directory contents, every commit from this point on will present you with this massive amount of export noise.
  4. To add insult to injury, the module you just installed has its English config added to your active config as DE, even though the strings are EN. Have fun translating those from German (not really) to... German?

So I cannot stress enough how much I agree with #48: Keep config/sync EN, always. Even if the website later turns off English, its main config should still be the shipped language and its translations could be found in config/sync/de. English is the only language we can rely on as the main config, because that's what everything ships with.

It seems like the current system is trying to make up for the fact that you can install English config in a non-English website, and doing so in a buggy way that leads to data loss and head aches for agency workflows.

I'd much rather have a consistent system that does not make any quality-of-life assumptions over one that changes my entire config directory automagically at unexpected times (module install).

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

nod_’s picture

Ran into this several times and thanks to this issue finally understood why... from experience, agreeing with #51.

In that spirit can we rename the test? The name testConfigTranslationWithForeignLanguageDefault is definitely wrong. That case is precisely to test things when the "english" language is the "foreign" language. Can we name that testConfigTranslationWithNonEnglishLanguageDefault, it would be more helpful and accurate.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

rar9’s picture

Another 2 Months have passed since my ticket was closed - https://www.drupal.org/project/drupal/issues/3161643#comment-13765390

Drupal 9.1 is approaching soon. Will this CORE bug be resolved in the coming release?

Will any of the above patches fix my Maintenance bug?

anybody’s picture

Whao after years I found the issue for this nasty bug :D Hope that someone is finally smart enough to find a solution for this complex problem. Critical++ for non-english projects.

2019 I wrote this Gist to find and delete equal translations caused by this bug. Perhaps this may help some of you:
https://gist.github.com/JPustkuchen/a101fa7ba257b8a7f8c3224f8bf5cc49

Anyway they don't seem to be recognized / updated by localization update afterwards to the correct value.

Update: We created a helper module for cleaning up such wring localizations:
https://www.drupal.org/project/l10n_tools

sander wemagine’s picture

I'm facing the same issue on every single D8 site I create for my clients. I also agree with #51

  • All my sites are created with Dutch as the default language and English enabled.
  • After every new module install the config export is polluted which is very, very time consuming to figure out what files have really changed. Very frustrating.
  • When I change the default language back to English the problem is still occurring.

How are you dealing with this? The only solution I can think of is manually going through every single file in the config export. Reverting every wrong config file and keeping the ones that really have changed.

kristiaanvandeneynde’s picture

Re #57 I ended up setting the default language to EN, but default language detection to NL. So config is treated as English, but when someone visits the site they see NL by default unless they visit /en, in which case they see the English version.

Very shitty workaround and I recall facing a bug that way, but it worked out in the end and config was no longer polluted as it would export the default as EN and the NL translations into the NL subfolder of the config.

sutharsan’s picture

I've been using this workaround for the past 3 years without any problems. I advise it for all single language sites. Default language: English, All lanuage detections off, Selected language (default detection): Dutch.

ayalon’s picture

We also experience this issue and for most of our projects, changing he default language now is no more an option. So we have to live with the fact, that after every module install, we have to manually fix 100+ config files.

askibinski’s picture

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

rar9’s picture

Is this patch perhaps helping to fix my Issue?
https://www.drupal.org/project/drupal/issues/3161643

anybody’s picture

Any news on this truly critical issue? I'd rate this as one of the most critical bugs still present in Drupal 9 at all! But it seems a bit underrepresented as perhaps many projects are simply in English for the US Community? (No offense - I simply can't understand how this can be open since 2016 - but I'm also not experienced enough to help in this case, so don't take this too seriously. This is open source, I know :) Just wanted to point out the pain for non-English projects with this.)

I completely agree with #48 and #51 as English is the Drupal "Base" language and will be. At least a working patch which assumes that and prevents the global community from this annoying bug (fix translations after each module install is an incredible pain, and we had many upset D/A/CH customers for this reason).

Who is able to decide how to proceed here? Let me know how I can help.

dmitriy.trt’s picture

StatusFileSize
new953 bytes

Attaching a patch that simply disables the sync between locale & configs. Sometimes it's more important to keep string translations made by the project team and avoid any data loss and it's OK to lose community translations of the shipped configs. The patch doesn't include the tests.

About the issue itself, just as an idea we could implement later. What about replacing the sync with another layer of config overrides provided by the Locale module and built on-the-fly? It could take string translations from the Locale storage and build an override for shipped configs. I guess, we must check that source strings are still the same in active config comparing to the shipped one. And we should probably ignore any strings in the config if it's not in English. It should solve this and multiple other issues resulting in some unexpected behavior and data loss, because we just won't write anything - neither locale strings nor configs. Do you see any issues with this approach?

casey’s picture

The scenario described by @gabor in #2806009-47: Installing a module causes translations to be overwritten made me understand this issue a whole lot better.

I actually like this features of progressively updating missing translations and keeping locale/config translations in sync.

However, I'd like to mention another scenario, which I think, a lot of others encounter and that the current implementation/behavior does not handle properly or at least different than many would expect:

Scenario:

  1. You have a site with default langcode != "en";

    lets say "nl" (Dutch);
  2. You alter translatable properties from config that origins from shipped (aka default) config to something that is not a translation of the shipped property value;

    For example you set the prevent/next pager labels of views.view.content from "‹ Previous" and "Next ›" to "Vorige pagina" and "Volgende pagina" (english translations would be "Previous page" and "Next page"), because you like to have the pager of that view to be more verbose.

Expected behavior:

  • The views.view.content view displays "Vorige pagina" and "Volgende pagina" as pager labels;
  • but other (not manually altered) views originating from shipped config (e.g. view.view.comment), display the original pager labels; that is "‹ Previous" and "Next ›", or if/when translated "‹ Vorige" and "Volgende ›"

Actual behavior:

  • The locale module assumes you have translated the pager labels "‹ Previous" and "Next ›" and updates/synchronizes the locale translation of "‹ Previous" to "Vorige pagina"

    This is incorrect/unexpected behavior, as "Vorige pagina" is not the actual translation of "‹ Previous"
  • On a next locale/config translation synchronization the pager labels of other views (but also every other config object) are updated to "Vorige pagina" and "Volgende pagina"

    I think this is actually correct/expected behavior as we want locale/config translations to be in sync and missing config translations to be progressively added

Currently available solution(s):
Some, like #2806009-59: Installing a module causes translations to be overwritten, try to circumvent the current behavior by always setting the default langcode to "en" and make the language detection select the actually wanted language. I do think there are valid arguments to do so. Like when you want your entire codebase to be available in English so it is better maintainable by international teams.

I do however like the (currently available) possibility of having a site's default available in a non-english language; this saves you from the burden of first finding the English translations of the texts/labels you like to use on your site, then create config in English and then translate it (in Drupal) to the actual site language.

Currently it is already possible to prevent Drupal from updating/overriding translatable properties of existing config on config/locale sync (e.g. after new module install):

Simply remove the _core.default_config_hash from the config objects you no longer which to be updated/overridden during config/local sync. Then the locale module will no longer consider this config to be originating from shipped config, and therefor no longer update/override the config.

Note that currently, locale is the only core module that uses this _core.default_config_hash property; it even doesn't check the hash, just if the property exists. Issue that introduced of this property: #2625258: LocaleConfigManager::updateConfigTranslations() deletes translations if a config object's name happens to match that of a shipped configuration object (Change record: https://www.drupal.org/node/2653358)

Drawbacks of this currently available solution:
The config you removed the _core.default_config_hash property from, is no longer recognized as "originating from shipped config". As a result, at least, translatable properties (that were not intentionally replaced/overridden) of these config objects are nog longer progressively translated nor kept in sync with locale translations.

Also, modules that use this info that a config originates from shipped config (not sure, but maybe https://www.drupal.org/project/config_sync), can no longer considers these config objects with removed _core.default_config_hash property from originating from shipped config.

On the other hand, I also think that there are scenarios in which config is altered in such a way that it no longer should be considered to be a copy/instance of the shipped configuration. In such scenarios I think it is correct to remove the _core.default_config_hash property.

Improvement suggestion:
Maybe we can introduce the possibility to mark translatable properties (of config originating from shipped config) as replaced, and skip these properties in the locale/config translation sync.

For example views.view.content.yml:

...
_core:
  default_config_hash: Abc_Xyz-123...
  replaced_translatable_properties:
    - display.default.display_options.pager.options.tags.previous
    - display.default.display_options.pager.options.tags.next
...

Later on, e.g. to improve this for site builders that don't store config in a vcs, we could add a UI.

casey’s picture

Another idea I just came up with: allow config to reference a translatable string. We could just use the twig syntax... If we'd support this for all translatable config properties, we could even replace the English string with these "references" when importing shipped config as non-english...

E.g. views.view.content.yml:

langcode: nl
...
displays:
  default:
    display_options:
      pager:
        options:
          tags:
            previous: "{% trans '‹ Previous' %}"
...
    some_label: "{% trans 'Order' with {'context': 'Commerce'} %}"
...

I might even like this better... Now that I am on to it, I think this could work in a way similar to what @Dmitriy.trt suggested in #65... we wouldn't need no locale/config translation sync no more...

Also, you should be able to use this in non-shipped translatable config properties; if you like to use a

Another benefit is that you could replace a "translation reference" in a translation of a config object with a custom translation, while other config translations automatically use the locale translation.

A downside however is that config is no longer completely static... Not sure if we already have other situations where exported config is "dynamic".

Another downside/problem maybe is, that users that can create/edit config would be able to create new translatable strings.

casey’s picture

I have created #3239026: Allow translatable config properties to reference a translatable string to further investigate/discuss the "translatable string reference" solution.

casey’s picture

jose reyero’s picture

Fascinating thread which is a good summary of all what is wrong with the config translation / localization system. Specially @Berdir #35 and @Gábor #36 and following comments. And I actually agree with all of them at the same time- call it 'quantum agreement'. So just trying to do some recap and adding some more perspective here.

The short version is: Drupal localization/configuration/translation gets messed up when default language is not English. And yes, I use @kristiaanvandeneynde and @Sutharsan workaround in #58 most of the time. It kind of works but it doesn't really fix the issues here.

First we have some hard-coded assumptions:

A. Default configuration is / must be in default language.
B. Shipped configuration is / must be always EN
C. Locale translation === Configuration translation

Then we have some 'translation rules':

1. When default configuration == shipped configuration, it is English and it is translatable through locale system
2. Default configuration is edited/saved using default language.
3. Locale translates configuration too, configuration translation updates locale strings
4. Locale system is the 'source of truth' for string translations, also for configuration.

Ok, then what can possibly go wrong? Just some cases:

X. When switching default language, default configuration language is switched too. It is stored as 'translated' even when it is not. - But as per assumption A. it *must* be default language, so cool, I guess.
Y. Locale updates translate default configuration automatically, when it matches shipped strings. At this point my deployment is broken - at the end the resulting config may not match the deployed one.
Z. Different issue, but... When I edit / translate configuration many default strings get saved as translated too, even when I haven't edited them. Some of these translation forms are huge...Think views.

Really, though our 'translation rules' look ok, I can see some 'resulting inconsistencies' so I'm wondering whether a)we are starting with the wrong set of assumptions, or b) maybe we just go too far with automatically updating translations...
Whatever, I completely agree with @Berdir #38 "the current sync is problematic in many ways though, there's a reason we have critical issues like this one open for years :)"

I'd like to ellaborate on a) wrong set of assumptions -that are not workable-, so maybe it's time to revisit the whole approach... will follow later...

andypost’s picture

Great point Jose Reyero! I think the primary point is X - When switching default language

That's a main unsupported case which sadly happens too much often, and that's what we should reconsider or revamp

jose reyero’s picture

So... following up on my previous comment, since the main issue seems to be the need -we've pushed upon ourselves- to have default config forced into the default language -that may be actually translated or not but we cannot know for sure- I'm thinking two options here:

1. We keep default confing in whatever language it comes, that may be 'en' for the one coming from shipped modules or 'default-lang' for newly created config.
• We use language overrides for any translations of that. Automated translations will only produce language overrides, never touch default config.
• No randomly changing language for default config. If the admin wants to change default config language we can provide some language field in the UI for that.
• Yes, this may support custom modules shipping default config in other languages, which I think is nice. (!)

or

2. We keep default config language-less, store any translatable string in language overrides.
• This includes English too, which will be somehow 'downgraded' and forced to use language overrides too
• We'd need some language fallback system that will go like 'current lang' -> 'default lang' -> 'english'
• No more mess wondering which language a config string is in or whether it is translated or not yet. Either we have the string for a language or not -then fallback.

JvE’s picture

Okay, let me add our use-case.

  • We have 1 codebase, everything in it is english.
  • We have 4 countries that use this codebase, each with a different default language.
  • Country admins create and maintain their own user interface translation.
  • We update db and import config when we deploy.

This works fine.
Until a deploy installs a new module.
Then the country admins suddenly lose a lot of their translations.

Let's say the German site admin has user-interface translated "Apply" to "Anwenden".
Every time a module is enabled, this changes into "Apply" being translated to "Apply".

Why? Because:

  • locale_system_set_config_langcodes() changes the langcode config of a view to 'de'
  • \Drupal\locale\LocaleConfigSubscriber::onConfigSave() calls UpdateLocaleStorage
  • \Drupal\locale\LocaleConfigSubscriber::updateLocaleStorage() calls processTranslatableData
  • \Drupal\locale\LocaleConfigSubscriber::processTranslatableData calls saveCustomizedTranslation
  • \Drupal\locale\LocaleConfigSubscriber::saveCustomizedTranslation tells the locale system that "Apply" is a customized German translation of "Apply".

Why? Because:

  • $langcode == 'de'
  • $source == "Apply"
  • $existing_translation == "Anwenden"
  • $new_translation == "Apply"
  • $locale_translation->isNew() == FALSE

Why this method decides that in this case the existing "Anwenden" needs to be replaced by "Apply" is beyond me.

*edit: this is allowed because LocaleConfigSubscriber is of the opinion that deleting/resetting a translation is done by saving a customized translation where the source and translation are the same?!?!?!

dmitriy.trt’s picture

As a follow-up of #65, attaching an updated dirty fix that additionally disables langcode updates on module installation, just in case it's useful for someone else. Otherwise, please ignore it.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

yonailo’s picture

Re #59 : but if you do like this, then you are forcing your contributors to publish/create a page in EN first (default site language) in order to be able to create a translation in Duch ? What if you don't want to have EN at all ?

Edit : I've just realised that we can create a page directly in a language that is not the default site's language, so please disregard the above paragraph :)

ericdsd’s picture

Hi, this issue alongside with related Configuration langcode is forced to site default language(and related) could IMHO really benefit of @Gabor and others presence at Drupal Dev Days to help making those tricky issues move forward by combining their expertise on this.

Actually bunch of cross referenced issues seems highly dependent even if focusing on a specific part of it, which contributes to make those unfixed by dividing the effort (while they each provide interesting insight).

I'm available to test patches if needed.

gábor hojtsy’s picture

I was at DevDays but did not realize this was to be a focus there?! Or I forgot mid-way. I don't remember that anyone worked on this there?

gábor hojtsy’s picture

Issue summary: View changes
StatusFileSize
new261.96 KB

To make up for that and because I had a lengthy discussion about this with Peter Wolanin just now, here is a drawing of how this maps out with user stories and where things are happening and code and why. This should also help with what you are giving up if you either use the MR or the patch, both of which block parts of this flow. The MR currently blocks making the config a different language code, so it essentially stops all the rest of the flow then. But that also means the Views UI, field UI, etc. will always show the config in the shipped language which may be a language not even desired on the website.

I don't know where the bugs are, but these are the user stories and flows implemented by core. Hope this helps those who do experience the bugs to find solutions :)

Caveat: the above figure is specifically for this bug. If the site default is English, then the translation will NOT end up in active configuration. And other translations will always be in configuration overrides.

mupsi’s picture

Hey Gábor, we talked briefly about this issue but we were already working on Localize, so no one in our group was available to check this issue unfortunately. I'm not aware of anyone else working on it during the dev days.

gábor hojtsy’s picture

@Mupsi: ah yeah, at least this chart may be helpful now to see where things may go wrong for people. Fingers crossed.

kristiaanvandeneynde’s picture

I might be mistaken, but I don't see how any of the workflow outlined in #81 would not beachievable by following what I wrote in #51:

  • Default config is always saved under /my/sync/folder
  • Any language is saved under /my/sync/folder/LANGCODE
  • If the site is French only, you have two folders, but the system defaults to searching in the FR folder, falling back to the default if nothing is found

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

seanb’s picture

I'm not familiar with the actual details of how / why core currently works the way it does, but from the perspective of someone that regularly works on multilingual sites (and the config langcode struggles that come with it), I like the solution kristiaanvandeneynde outlines.

Having a config folder that exports the "en" version of the config (whether the language is enabled or not), and having language-specific folders that contain the config for a specific translation (and maybe even the translatable parts only).

This also seem to be in line with string translations. When adding translatable text in code, the language is always English. Sites can export/import the translations of all other languages.

ysamoylenko’s picture

Confirming that #2806009-76: Installing a module causes translations to be overwritten works, but wondering why configuration import causes interface translation updates with incorrect default language selection.

I totally agree with @kristiaanvandeneynde in #2806009-51: Installing a module causes translations to be overwritten and #2806009-84: Installing a module causes translations to be overwritten, this approach possibly may avoid any configuration and translation conflicts.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

ankithashetty’s picture

Have applied a patch for a related issue. Just putting it out here so that anybody can review this if it works for them or not.

Final patch in https://www.drupal.org/project/drupal/issues/2845437#comment-14875699. Have shared thoughts in my previous comments in that issue.

Thanks!

jose reyero’s picture

Hi @kristiaanvandeneynde I basically agree with your idea #51 about keeping the default config in the language it comes - ok, let's assume English.... but also, maybe, for the future... #74

About the excelent diagram in @Gábor Hojtsy #81 just outlines the current situation / behavior, not a goal nor a solution in itself, it is just a must read to understand this issue.

So, if we can agree about keeping the default config in English, that would be a good starting point, there are a lot of pieces we have to adjust for that to happen and produce a solution:

- The initial configuration import, we should do no translation on that one. This looks like the easier one...
- The Config edit UI -which is all around the site needs to 'be aware' of that too, and should edit only the right language configuration, not the default one.
- This may require redefining how config / config_translation -which is a different module, may be enabled or not - work together.
- Then what happens with newly created config, i.e. a new field... ? How do we store that one, should we create translation right away, mark it somehow, etc.. ?

Then we have multiple site-building paths like 'what happens if' you start single language but not English, then add some more, then enable / disable config / interface translation, then change default language, etc... Whatever we do, in whatever order, it needs to produce some consistent state so my guess is that will need some harder coupling / requirements between modules - language / config translation / interface translation -
... Not that it happens now which is also a bug by itself but if we are working on this we should try to get it right at once...

So... those are a lot of things... that's why I insist we need to agree on some basic approach before wasting too much time on patches.

xen’s picture

Here's another odd consequence of the current system: Have a site with `da` as default language, enabled a module which set `da` as langcode for all config, even though the current texts are English. OK, they're translated by locale, so things work.

Now I create a text format and export it. Which causes something to update `user.role.authenticated.yml` and `user.role.anonymous.yml` to contain Danish strings. Which makes the language code of the file more correct, but as far as I understand (someone please correct me if I'm wrong) this means that the user roles names will *not* be updated if the translation changes? I think this goes against the intention in the graph of #81. Why on earth were these updated?

Anyway, while I understand wish to make the "core" configuration english and layer translations on top, it'll have another problem: configuration without an english default. If a danish user on a danish site (with danish as the default language) creates a new role, it's obviously in danish. As it's a new role, we don't have an english string to put in the configuration.

Is a dual mode feasible? When configuration is imported on install, it's installed with `en`, but if a user saves a configuration page, it'll be assumed to be the default language, unless there's already a translation overlay?

xen’s picture

> Why on earth were these updated?

Turns out that, when configuring a role to have access to a text format, it adds a config dependency from the role to the text format. So that explains why the role configuration was touched. But I'll still consider it a bug that it changes the untouched label from English to Danish.

alexpott’s picture

Status: Needs work » Needs review
StatusFileSize
new3.26 KB

I've got this bug on a multilingual site I'm working on so I spent a few hours in the debugger trying to work out why this is happening and I tracked it down to my old friend \Drupal\locale\LocaleConfigSubscriber. What was interesting is that this was being triggered by a config save in locale_system_set_config_langcodes() which is called whenever a module is installed. There's no way that the strings from configuration which is having its langcode alter here should end up in as translations. Fortunately LocaleConfigManager already has a way for us to disable the effects of the config subscriber. Once we do this on the site I'm working we're no longer losing translations and in fact more things that should be translated are!

Let's see if this fix breaks any tests.

alexpott’s picture

StatusFileSize
new3 KB
new6.26 KB

Adding @jhodgdon's test from #12 which still fails and is great outline of the issue that #93 fixes.

The last submitted patch, 93: 2806009-93.patch, failed testing. View results

alexpott’s picture

The last submitted patch, 94: 2806009-94.test-only.patch, failed testing. View results

alexpott’s picture

  1. +++ b/core/modules/locale/locale.module
    @@ -370,28 +370,7 @@ function locale_cron() {
     function locale_system_set_config_langcodes() {
    -  // Need to rewrite some default configuration language codes if the default
    -  // site language is not English.
    -  $default_langcode = \Drupal::languageManager()->getDefaultLanguage()->getId();
    -  if ($default_langcode != 'en') {
    -    // Update active configuration copies of all prior shipped configuration if
    -    // they are still English. It is not enough to change configuration shipped
    -    // with the components just installed, because installing a component such
    -    // as views or tour module may bring in default configuration from prior
    -    // components.
    -    $names = Locale::config()->getComponentNames();
    -    foreach ($names as $name) {
    -      $config = \Drupal::configFactory()->reset($name)->getEditable($name);
    -      // Should only update if still exists in active configuration. If locale
    -      // module is enabled later, then some configuration may not exist anymore.
    -      if (!$config->isNew()) {
    -        $langcode = $config->get('langcode');
    -        if (empty($langcode) || $langcode == 'en') {
    -          $config->set('langcode', $default_langcode)->save();
    -        }
    -      }
    -    }
    -  }
    +  Locale::config()->systemSetConfigLangcodes();
     }
    

    If we commit this (and I think we should) we should open a follow-up to deprecate locale_system_set_config_langcodes() in 10.x because we no longer need it.

  2. +++ b/core/modules/locale/src/LocaleConfigManager.php
    @@ -649,4 +649,34 @@ protected function filterOverride(array $override_data, array $translatable) {
    +  /**
    +   * Updates default configuration when new modules or themes are installed.
    +   */
    +  public function systemSetConfigLangcodes() {
    

    LocaleConfigManager has no interface so adding the method is allowed under our BC policy.

  3. +++ b/core/modules/locale/src/LocaleConfigManager.php
    @@ -649,4 +649,34 @@ protected function filterOverride(array $override_data, array $translatable) {
    +    $this->isUpdatingFromLocale = TRUE;
    +    // Need to rewrite some default configuration language codes if the default
    +    // site language is not English.
    +    $default_langcode = $this->languageManager->getDefaultLanguage()->getId();
    +    if ($default_langcode != 'en') {
    +      // Update active configuration copies of all prior shipped configuration if
    +      // they are still English. It is not enough to change configuration shipped
    +      // with the components just installed, because installing a component such
    +      // as views or tour module may bring in default configuration from prior
    +      // components.
    +      $names = $this->getComponentNames();
    +      foreach ($names as $name) {
    +        $config = $this->configFactory->reset($name)->getEditable($name);
    +        // Should only update if still exists in active configuration. If locale
    +        // module is enabled later, then some configuration may not exist anymore.
    +        if (!$config->isNew()) {
    +          $langcode = $config->get('langcode');
    +          if (empty($langcode) || $langcode == 'en') {
    +            $config->set('langcode', $default_langcode)->save();
    +          }
    +        }
    +      }
    +    }
    +    $this->isUpdatingFromLocale = FALSE;
    

    There are no changes to the logic from the original function here. The "magic" is wrapping it in $this->isUpdatingFromLocale = TRUE and $this->isUpdatingFromLocale = FALSE. This prevents LocaleConfigSubscriber from making incorrect changes to the configuration.

  4. +++ b/core/modules/locale/tests/src/Functional/LocaleConfigTranslationImportTest.php
    @@ -305,4 +305,66 @@ public function testLocaleRemovalAndConfigOverridePreserve() {
    +  /**
    +   * Tests setting a foreign language as default and importing configuration.
    +   */
    +  public function testConfigTranslationWithForeignLanguageDefault() {
    

    @jhodgdon thanks for the test that still works and proves the fix :)

jose reyero’s picture

Hi @alexpott, this looks a pretty interesting cool fix...

The part I'm missing though is that isUpdatingFromLocale = TRUE ... "Whether or not configuration translations are being updated from locale"...
... because this is not actually updating configuration translations from locale, it's a module install and we are just setting the config language to the default one... so even if it is somehow working (yes, we are preventing the locale system from attempting to automatically update strings from that or do anything else with that configuration), maybe we should revisit the concept of that variable....

Not sure, but maybe just changing the description to "Whether or not configuration updates are being triggered from locale, either for saving a configuration translation of for setting the configuration language." would do... ?

kristiaanvandeneynde’s picture

Re #90 I agree with the starting point of keeping default config in a single language and that it should be English.

What I would suggest is this:

  • Config folder (e.g.: /config/sync) contains all the config that ships with core/contrib and (as already is the case) that should be in English
  • You configure your site to use whatever language you want (English is also a deliberate choice)
  • This creates the corresponding config folders, e.g.: /config/sync/en, /config/sync/de, etc.
  • New config handling:
    • Whenever config is created via installing new code, it copies the config ONLY to the sync folder
    • Whenever config is created via the site, it puts it in the sync folder AND the language folder of the current route's language
  • Config requesting:
    • Request in the active language, if none is found show the sync folder one
    • When adding a translation, it copies all values at first, but you can then modify as you see fit
    • This fixes the concern from #91 because you are free to add your own new config in Spanish or whatever. As long as distributed code (aka D.O. code) ships in English, you can do what you want.

So there is no hard requirement for personally created config in your sync folder to contain English strings. Core should therefore not contain any code that assumes the central folder has English text. But, to make everyone's life easier, core and contrib are still required to ship their config in English.

geek-merlin’s picture

Some months ago i took a day off to find a pragmatic solution for this WTF for our team.
It ended up creating the MultiLangNG module. Which we successfully used in some projects now.

Which makes me confident to throw its hat into the future-of-core ring.

What does it do? It stops the sync magic (translations / config overrides) and does runtime config overrides instead.
This brings back the (remember D7?) contextual translations, and brings a cozy empty language override directory.

jose reyero’s picture

Please lets keep us focused here.

(And yes I am the first one guilty of trying to extend the scope of this thread rebuilding the whole config translation thing but...)

* If a simple solution like @alexpott #94 works and fixes this issue, we should go for that.
* I still want some better config translation @kristiaanvandeneynde but that is a complex and lengthy one, maybe for a new task.
* Loving some of the ideas in MultiLangNG module, @geek-merlin, you had it well hidden - lack of module description.... you'll see me around that one... :)

alexpott’s picture

@Jose Reyero thanks for #102. I agree that completely re-structuring how config stores translations and deals with a default language other than english needs a separate issue and #101 also would need a completely separate issue.

Re #99 I'm not sure that we need to update the description for the flag. This flag is also why all the configuration changes made by calling locale_system_update() don't result in LocaleConfigSubscriber making changes.

In fact I think that we should move the call to locale_system_set_config_langcodes() inside locale_system_update() - it's not really a separate thing.

alexpott’s picture

StatusFileSize
new9.4 KB

Part of the problem here is the distance between when locale_system_set_config_langcodes() runs and when the call to locale_system_update() eventual does the config update in the batch process using locale_config_batch_refresh_name(). The code in #94 reduces this gap massively for module and themes post site install but the gap is still huge during a site install. This can result in unexpected changes during site installation.

The solution here is to move the updating of the default langcodes into the batch created by locale_config_batch_build(). This makes the updating of the default langcodes run at the correct time regardless of when locale_system_update() is called.

VladimirAus made their first commit to this issue’s fork.

alexpott’s picture

StatusFileSize
new3.66 KB
new11.35 KB

Turns out that locale_config_batch_update_components() is never called with a list of components so we need to pass along a flag...

geek-merlin’s picture

@Jose Reyero # 102
> Please lets keep us focused here.

You are right and wrong. Up to some days ago this was effectively a meta issue with a fruitful discussion of potential approaches. I missed the shift in the discussion, and i think it was wrong, because it buries a good conversation. And we do that too often.

Rant aside, here's the two issues.

jose reyero’s picture

@geek-merlin
I like being right and wrong at the same time, sounds like quantum computing... :)

So yes, and no... :D .. We need to fix this issue ASAP, which I can understand is a major headache for users. And we need to get a cleaner config translation workflow so we developers can have some peace of mind with Drupal translation. Thinking about creating another issue like "Do not mess with the language of the default configuration" or similar... and maybe some copy & paste and linking of comments here will help..

So, about @alexpott patch:

* Ok, about flag description, not that important anyway, it's the flag itself that's some hack.
* Not so sure about changing also locale_config_batch, that makes the patch 10x more complex
I think that batch is invoked from more places, unlike locale_system_set_config_langcodes() which was called only on module/theme install
* I liked more the previous patch #96.. but not sure about what else this latest one fixes - besides saving a function call, but that two steps also made the logic cleaner... (?)

alexpott’s picture

What #106 does is reduce the time between when the langcodes of default config and the locale_config_batch_refresh_name() is called. This vital to ensure that problems do not occur. When this called after site install the implementation in #94 is okay. But all this code also runs during a site_install. Where the gap between updating the langcodes of the config and doing the config translation involves the chance of other modules making changes that will break the assumptions that we are making by doing locale_system_set_config_langcodes() and then locale_system_update() in the install hook.

We should never have put locale_system_set_config_langcodes() outside of the batch triggered by locale_system_update() - when we implemented that we just did it in the simplest way possible without thinking about the difference between site install and extension install after site install.

geek-merlin’s picture

@Jose Reyero # 102
> We need to fix this issue ASAP, which I can understand is a major headache for users.

Did you understand that #101 fixes this bug completely and thoroughly? And is there today?
(So if that's tha focus, i'm more focused ;-), and please forgive my insistance). (You can answer in the other issue if you want)

jose reyero’s picture

Well, the more I test this, and think about it... yes... installing new modules when your default language is not English is a terrifying experience !!! Stll worse when you are doing it while deploying to production... :(_

So reconsidering a little bit... I think there is only one time when we should run that locale_system_set_config_langcodes() and that is *after a site/profile install* ... and never triggered after single extra modules are installed. That should also fix your issue "to ensure that problems do not occur" @alexpott?

(I've also noticed what happens when first you switch default language... nothing yet... but, then you configure something else, then you install some new module... then... boom!... configuration translations kind of implode... :.oO )

So I'm wondering, what if:

* We fix this annoying thing with locale/config_translation re-trans-translating itself, that would be #94 (still preferred) or #104 (makes some sense, but also makes it way more complex)
* We also kick that locale_system_set_config_langcodes() function out of hook_modules_installed() to somewhere after profile install.

?

I mean would this make everybody happier? - Not 'happy', just 'happier'... ok?

And yes @geek-merlin #101 will fix this issue for some people now you've added a description to the module ;) thx

alexpott’s picture

@Jose Reyero I agree that a follow-up needs to be filed to determine what to do when a site changes it's default language. FWIW this is a super scary operation that is really not well supported. Also people are trying to share configuration across sites with different languages - see #3150540: Configuration langcode is forced to site default language - that's just incredibly difficult if we're going to save translations in configuration - the approach that issue takes feels incredibly wrong and points us towards a solution like #3336728: Translate config at runtime (aka MultiLangNG in core)

With respect to changing how the current system works - I don't think we can change the fact that module install sets the default language for new configuration. What we can do and this patch moves toward is to make it more targeted and have less time when the system can possibly interact with configuration where the langcode has changed but locale has not had a chance to translate it yet.

The patch in #106 reduces the time between the langcode update and config translation on an install for both site install and extension install and therefore I think this is the patch we should commit to stop the rot and stop breaking people's configuration.

anybody’s picture

Totally agree with #111 and #112 (+ 1mio ;)) as someone who runs into the issues since day 1 and on all German projects. Thank you all for your great work and investigations.

Especially I agree it's better to improve the situation safely ASAP and proceed in follow-ups instead of keeping it for further years. This is surely one of the most critical issues for non-english Drupal projects of all sizes.

jose reyero’s picture

Ok,

I agree @alexpott's patch, any of them, is an improvement over what we've got atm and it should fix the main issue on this task.

Code looks good, though I didn't have the time for thorough testing yet.

As a side note, and ok, for a new task, the workflow when changing default language is badly broken... just wondering whether to create a new task or there's one already. (?)

alexpott’s picture

@Jose Reyero I created #3337864: Configuration language is not adjusted after changing the site default language as I could not find a specific issue.

I will try to explain again why #106 is the correct patch, but I'll do it with a test that would be broken with #94. Patch incoming...

alexpott’s picture

Here's the additions to the test that prove that the changes to the batch are necessary to fix this problem.

alexpott’s picture

jose reyero’s picture

@alexpott

Thanks for creating the other tasks, I'll follow there..

Only, about your new test... so a module edits its own configuration on hook_modules_installed... and that makes its own translations get messed up... I mean LOL! ...

But OK, let's say it's a valid use case... It only makes an stronger case for #111 ... We should never run that locale_system_set_config_langcodes() upon module installs... and it would also pass this test ... :D

Anyway... this is a +1 from me, or maybe a +2 seen that it can also pass the trickiest install test ;)

More reasons for this patch @geek-merlin... by moving the locale_system_set_config_langcodes() into the LocaleConfigManager service, it will be much easier to knock it out using service overrides. (!)

alexpott’s picture

But OK, let's say it's a valid use case... It only makes an stronger case for #111 ... We should never run that locale_system_set_config_langcodes() upon module installs... and it would also pass this test ... :D

No it wouldn't pass this test. Because config would not be translated correctly. Stopping the langcode of default configuration from being changed on module install will take a pretty hefty re-write of how config translation works. Just doing that on its own would actually result in a more broken system. Because you'd have a mix of languages in the default config collection. Config created during site install would have 'en' whereas config created by the user after would have the site's default langcode.

alexpott’s picture

@Jose Reyero is a +2 enough for a rtbc? It would be great to stop the rot this problem causes and also move on #3337864: Configuration language is not adjusted after changing the site default language which really needs this change in order to work well.

jose reyero’s picture

@alexpott

> is a +2 enough for a rtbc?

I'd really like someone else to give some more feedback here, maybe that RTBC. I mean it's been 5+ years discussing this one, it feels like while closing the original bug report, we are leaving a lot of issues unanswered.

Also I share some of @geek-merlin #107 concerns:

Up to some days ago this was effectively a meta issue with a fruitful discussion of potential approaches. I missed the shift in the discussion, and i think it was wrong, because it buries a good conversation. And we do that too often.

alexpott’s picture

@Jose Reyero well if we want to keep this ticket open we can move this patch to #2905295: Configuration language being overwritten during module install which is a duplicate critical issue. In my opinion we need to fix this bug ASAP (on whichever d.o nid we like) and then the changing default language issue. The ideas to completely change configuration translation come with their own set of issues and will need extremely complex update paths and deprecations of existing code. Also it is very likely that some of the existing functionality is untested and relied upon by some projects so whatever we do will create a new set of criticals.

anybody’s picture

@alexpott and @Jose Reyero: Strongly agree with #122 AND #123. You're both totally right and I think @alexpott's suggestion in #123 to improve things as far as possible NOW and improve the general concept even more carefully later, is the best thing we can do here (in my opinion)!

The worst thing we can do here, is to make things worse in code (definitely not the case, from my perspective with that fix) or wait for 5 more years (or even if less) to improve things. It doesn't have to be perfect, if it improves thing without making it worse! And I think, that's the case!

I'd have given the RTBC, but I'm not experienced enough to be 100% sure everything is fine. Perhaps @andypost, @geek-merlin or someone from the core team, who has a lot of experience on this topic, could sign this off?

geek-merlin’s picture

+1 for any improvement. Looked into the patch and it looks reasonable, but a thorough code review or rtbc is beyond my capacities these days.

geek-merlin’s picture

tra.duong’s picture

I have this issue.
Tried #76 and #106 patches.

My environment:
+ Drupal 9.5
+ Default langcode is Ja, monolingual
+ Check on '/admin/content/media'

Steps to reproduce the error:
+ install site
+ import configurations (views.view.media.yml in this case) which is langcode 'ja' and label of 'Status' changed.
+ `drush locale:check`
+ `drush locale:update` <-- issue appeared here

The result is `Status` label is fallback to the translate of string `Status`, not the already translate string in `views.view.media.yml`
=> The translation of views change unintentional.

About patch #76: It not change the text in this case, but it is too brutal.
About patch #106: The configuration is changed.
I have a check on `vendor/drush/drush/src/Drupal/Commands/core/LocaleCommands.php::update`
it call locale/locale.fetch.inc::locale_translation_batch_update_build
Seems patch #106 does not take affect to the processing of this function

I agreed to @Anybody in #124. I raise a case when the patch may failed to deeper improvement

alexpott’s picture

@tra.duong your issue is not the same. The bug this issue describes and the fix only affects sites with more than one configurable language. I think what you are seeing is cuased by another view or config somewhere on your site causing the system to think that the Japanese for "Status" is "Status" - which even to a non-japanese speaker seems surprising ;). Check your other views & config files for a label that is set to Status and see if fixing that fixes the issue.

tra.duong’s picture

@alexpott, it not totally the same yes. Because for monolingual, which is not English, it try to switch back to English and override the translation in View
I mean it override the configuration of the already overrided view.
This behavior answer why patch #76 works. It ignore the 'switch back' in locale_system_set_config_langcodes()
The thing to consider here is, which is made by user must be kept, even when switch back to English is not identical.
I put my issue here, to give another factor of this issue to easier to evaluate.

alexpott’s picture

It'd be great if we could land this issue.

alexpott’s picture

Issue summary: View changes

Updating issue summary with the solution.

alexpott’s picture

Issue summary: View changes
alexpott’s picture

I've added a CR to cover the API additions necessary to fix this bug - https://www.drupal.org/node/3348540

alexpott’s picture

Simplest steps to reproduce:
1. Install minimal in German
2. Enable the views module after install.
3. Run the following query on the database: select language, source, translation from locales_source ls, locales_target lt where ls.lid = lt.lid and source = 'Items per page';

Before you will see:

+----------+----------------+----------------+
| language | source         | translation    |
+----------+----------------+----------------+
| de       | Items per page | Items per page |
+----------+----------------+----------------+

With the patch

+----------+----------------+--------------------+
| language | source         | translation        |
+----------+----------------+--------------------+
| de       | Items per page | Elemente pro Seite |
+----------+----------------+--------------------+
alexpott’s picture

FWIW what makes this bug even worse is that prior to installing views on the site on HEAD if you run the query you will see:

+----------+----------------+--------------------+
| language | source         | translation        |
+----------+----------------+--------------------+
| de       | Items per page | Elemente pro Seite |
+----------+----------------+--------------------+

So it's not just that we don't translate the new configs correctly we ALSO break existing translations.

anybody’s picture

@alexpott we can definitely confirm that from our daily experience ;)
One of the most annoying bugs in Drupal multilanguage, still existing...

smustgrave’s picture

Tested on Drupal 10.1 standard install with english starting off
Added German as a 2nd language
Set German to default language
Deleted English
Installed activity tracker
Went into User interface translation searched for Content and got the English word. See screenshot
Only local images are allowed.

Applied patch

Does not automatically change Content back. Think that's expected. Please confirm

Added English back as a language
Made default
Deleted German and I get this error

Deprecated function: Automatic conversion of false to array is deprecated in Drupal\locale\LocaleDefaultConfigStorage->read() (line 93 of core/modules/locale/src/LocaleDefaultConfigStorage.php).

May be unrelated Please confirm
Readded German
Verified on User interface translation the word content is translated
Made German default
Deleted English
Installed Activity tracker again
Verified on User interface translation the word content is translated still.

I'm good to mark this if those questions could be answered.

smustgrave’s picture

Actually may have found an issue.

Readded English
Made English the default
Went to Content types page. Things are showing as German still

alexpott’s picture

@smustgrave changing the default language via the UI is fraught there is an issue for that #3337864: Configuration language is not adjusted after changing the site default language - we need to fix this first in order to make that worth fixing.

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: +Needs Review Queue Initiative

Spoke to @alexpott about the issues in bold and they are not issues or issue that needs to be fixed here. So marking it.

alexpott’s picture

I've added instructions about how to fix an affected site to the CR - see https://www.drupal.org/node/3348540 - unfortunately this can not be automated.

anybody’s picture

@alexpott re #141 perhaps our module https://www.drupal.org/project/l10n_tools can help. It has the ability to remove equal translations and reset translation status, so that translations can be refreshed.

Of course, it's not an end user tool, but if it works for this case, it MIGHT be helpful to add it to the CR as contrib helper?

alexpott’s picture

@Anybody sounds like a good idea to me - go for it! If you can update with tested instructions for how it might work that'd be great. There's no real end user way of fixing a site.

alexpott’s picture

Notes to committers - this could be backported to 9.5.x - all the API changes are additions and have sensible defaults that align to the current behaviour.

catch’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/modules/locale/tests/src/Functional/LocaleConfigTranslationImportTest.php
@@ -305,4 +305,66 @@ public function testLocaleRemovalAndConfigOverridePreserve() {
+  /**
+   * Tests setting a foreign language as default and importing configuration.
+   */
+  public function testConfigTranslationWithForeignLanguageDefault() {
+    /** @var \Drupal\Core\Extension\ModuleInstallerInterface $module_installer */

Everything looks good, except this should be 'a non-English language' and the same with the method naming, which nod_ pointed out in #53.

Just a rename/docs change so fine to set straight back to RTBC with that change and I think I'm happy to commit otherwise.

catch’s picture

Version: 10.1.x-dev » 10.0.x-dev
Status: Needs work » Reviewed & tested by the community

Actually no - that's fixable on commit, so I've gone ahead and done that.

Committed/pushed to 10.1.x, thanks!

I agree this can be backported to 10.0.x and 9.5.x but will wait until we decide about a hotfix/early patch release for #3348592: [regression] Language switcher block throws exception when no route is matched first. If we bring the patch release forwards, would prefer to cherry-pick this just after that.

  • catch committed e029e6cd on 10.1.x
    Issue #2806009 by alexpott, JvE, Berdir, Dmitriy.trt, jhodgdon,...

  • larowlan committed f2bb7483 on 10.0.x authored by catch
    Issue #2806009 by alexpott, JvE, Berdir, Dmitriy.trt, jhodgdon,...

  • larowlan committed b74670f1 on 9.5.x authored by catch
    Issue #2806009 by alexpott, JvE, Berdir, Dmitriy.trt, jhodgdon,...
larowlan’s picture

Status: Reviewed & tested by the community » Fixed

The release for #3348592: [regression] Language switcher block throws exception when no route is matched is out, so I backported this to 10.0.x and 9.5.x and published the change record

andypost’s picture

Maybe change record needs changes as it was backported to 9.5??

catch’s picture

Version: 10.0.x-dev » 9.5.x-dev
bnjmnm’s picture

Adjusting issue credit as credit is not provided for button-click rebases without additional contribution.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

andypost’s picture

anybody’s picture

For the records:

We're still experiencing this in a Drupal 10.3 installation!

Exactly this:

f) Go to admin/config/regional/translate and search for the word "Content". You will see that its translation has become "Content" (English) instead of "Tartalom". Content type is also screwed up, but some other words are still translated... Screenshot:

still happens from time to time.

For us it's German. We translate it back to "Inhalte" and people to "Benutzer" and some weeks lates we again see "Contents" and "People" and the user interface translation was overwritten (admin/config/regional/translate)
So either this was not fully fixed or we have another issue.

I'm leaving this info here, if someone else should still have the same issue or if anyone can tell, what it's caused by.

We have it on projects with English as first + default language (and German as second) and on projects with German as first + default language (English as second).

rar9’s picture

+1... This issue has never been resolved and admin gui /views get messed up.

Parallel issues only get closed.

Drupal should be ashamed as its be ignored for so long.

My findings installing modules will cause this as drupal kind of experts to be English.

Time to move away.

anybody’s picture

Time to move away.

From Germany? 😁😉 - sorry just joking.

I understand your frustration and I agree that this is really problematic for all non-English Drupal users since the first day of Drupal 8, but please let's be friendly and thankful. This is a community and nobody is paid for this.
On the other hand I agree that this is one thing that really shouldn't happen at the maturity level of Drupal.

Anyway it's a hard and conceptional complex issue, which I also assume would have been fixed much longer, if the majority wasn't English, but it's like it is. And both of us didn't help much (or pay) to take this where it is!

So you and others can confirm exactly this issue still exists? Then it would mean the tests implemented here are not enough or we have a different, common reason why this happens!

Further information or investigations? Should this be reopened then?

xen’s picture

@anybody
Not very actionable input, but it's my impression from the time since my last comment two years ago that the language system still have some issues. Like the "why did it update all the language configuration files" thing that crops up now and again.

But this is hard to nail down, as developers are likely to just utter a curse, perhaps revert some files, and push out the feature that the customer requested, rather than spending hours trying to debug why it happens.

ericdsd’s picture

Hi, i've also just experienced something similar again, not with a module installation but with an update, most probably Upgrading drupal/core (10.2.6 => 10.3.6).
I have a site with English as default and french enabled, after running updb configs from few views taxonomy cocabularies and content types got some of their localized config strings replaced by french ones.

It could be related with
views views_data_argument_plugin_id post-update Post update configured views for entity reference argument plugin IDs.

node set_node_type_description_and_help_to_null post-update Converts empty `description` and `help` in content types to NULL
Concerning the content types and vocabularies it's only the description and help text that are replaced by their french translations.

achap’s picture

I re-opened an old issue that was closed in favour of this one which is still happening in 10.3. Interface translations are overriding config translations whenever interface translations are updated . Maybe best to concentrate efforts there if you are experiencing the same?

Interface translations override config translations on update

ericdsd’s picture

I really thought it was fixed, but the issue indeed seems to have respawn. On core 10.4.6 with french as default language, installing a module that has config/install (here it's language_switcher_extended) breaks a large amount of config translations (webform, backup_migrate, views ...). I'm available to help testing any MR.

anybody’s picture

I also have the gut feeling, that it's still happening under certain circumstances. Seems to happen more rarely, but after some time, certain translation strings still fall back to wrong default language. Nevertheless, I cannot rule out the possibility that contrib is involved.

ericdsd’s picture

Thanks @Anybody, if it can help i had this issue after enabling translation modules on an existing french only site that had the english language already available but no translation functionality enabled prior to that.

erwangel’s picture

Version: 9.5.x-dev » 11.3.x-dev

This is still happening in 10.5.6. Several - but not all, strange - of my Views translations are reverted to English each time I install a new module, despite default language is French.

staalex’s picture

Absolutely still happening, I see this quite often on 10.5.x. English configuration in config/sync (with langcode: en) are overwritten with german labels whenever a new module is installed

anybody’s picture

@larowlan: I can also confirm we're still seeing overwritten config translations happening unexpectedly. For example, Views that are set to "German" as default language suddenly have all English texts again, that were translated to German before.

That's surely one of the most critical Drupal issues we see regularly on multilanguage projects IN PRODUCTION. So I guess this should be re-opened and prioritized, or are there already other issues for this?

erwangel’s picture

After some testings it seems it happens when enabling new modules with drush en. Enabling with the Drupal UI I didn't notice the problem. Needs to be confirmed.

anybody’s picture

After some testings it seems it happens when enabling new modules with drush en. Enabling with the Drupal UI I didn't notice the problem. Needs to be confirmed.

I was not able to reproduce this yet FYI.

In our case I still think COOKiES might have caused this (#3219293: COOKiES settings translation affects Drupal Core localization translations in combination with unfixed #2910353: Prevent saving config entities when configuration overrides are applied)

ericdsd’s picture

On 10.5.8 i still have the issue, here only affecting webform and metatag.