Problem/Motivation
This issue fixes a regression from #3518992: Config overrides are loaded for English even when translate_english is false, see #36-38 over there for details.
Steps to reproduce
- Set up a Drupal project in German (or any other language != 'en') in the setup process (installation language)
- Translate some configs and see configs with
langcode: degenerated as default configs in the sync/ folder when exporting configuration - Switch the default language to English
- Translate some configs and see configs with
langcode: engenerated as default configs in the sync/ folder when exporting configuration - Now you have a mix of "default config translations"
- When using Drupal >= 11.3 you will furthermore see a regression, where the English translations are not loaded when using English as default language again (not having "Enable interface translation to English" checkbox enabled)
Proposed resolution
Unify all default config to always use the default language as langcode to save us from unexpected edge-cases and side-effects:
1. Write a script to convert all default configs to use the default language
2. Execute the script once in a update hook to fix the regression from #3518992: Config overrides are loaded for English even when translate_english is false
3. Execute the script (using Batch API) when ever the default language is changed
Furthermore, we could discuss if it wouldn't make sense to always (hard-coded) set the default language to en for config like it's consensus to have English as the default Drupal base language since ever. That might simplify things a lot in the future all over the framework.
Remaining tasks
Discuss
Implement
Test
Release
User interface changes
None
Introduced terminology
None
API changes
None
Data model changes
None
Release notes snippet
TBD
| Comment | File | Size | Author |
|---|---|---|---|
| #14 | 3568743-convert--unify--13.patch | 5.81 KB | grevil |
Issue fork drupal-3568743
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:
- 3568743-convert--unify
changes, plain diff MR !14439
Comments
Comment #2
anybodyComment #3
anybodyJust found the comment that referes to the point:
here: https://www.drupal.org/project/drupal/issues/3150540#comment-15532642
I still totally agree!
Comment #4
anybodyLooks like #3150540: Configuration langcode is forced to site default language implements a similar approach, but currently it looks like it won't work for the case where you later switched the default language to English from a different language?
Comment #5
anybodyComment #6
grevil commentedComment #8
grevil commentedDone.
Comment #9
dcam commentedI haven't done a code review of these changes, but there are a few issues with the MR as it's currently written:
hook_update_N().For these reasons I'm setting the status to Needs Work.
Comment #10
anybodyWHAO @grevil, works like a charm and cleaned up our messy config translations to be clean now. After running the update I was able to identify four lost legacy configs, now all is clean and working fine again!
I only had to do this step manually before executing the script:
$localeSettings->set('translate_english', TRUE)->save(TRUE);That doesn't seem to work in code yet, maybe some weird caching issues or something like that, not getting the actual, freshly set value in code?
Comment #11
anybodyOkay I found one major issue so far: Views configs!
Seems (at least in our case) some views are somehow cluttered into base and translated config and after running the script the base config seems to be incomplete someway. Important keys / options missing and this causes errors.
It doesn't affect all views, but core views and custom views, which is strange...
We need to investigate that further after fixing the other issues, before this can be used in production!
Comment #12
anybodyRe #11 I think I know the reason: If the found key in the translation override is an array, we need to get the original array and deep-merge the translation into it, with values from the translation overriding to become the new default config. Otherwise, we may have missing values in nested configurations, which especially happens for views (but also others, e.g. slick I could imagine).
Flat configs will work fine.
Comment #13
grevil commentedAlright, maybe some maintainers can take a look at the current code, if it is sufficient enough? When approved this should be put inside a service and called, once the language is switched.
Therefore setting to needs review for now.
Comment #14
grevil commentedStatic patch for the time being.
Comment #15
smustgrave commentedLeft comments but would be good to get a test case showing the problem.
Comment #16
eric_a commentedApologies if already discussed here or in the issue that caused a regression.
How does this relate to:
#3427564: Require `langcode: …` only for simple config that contains translatable values
#2628004: Create an upgrade path to determine if default_config_hash should be added (2625258)
Comment #17
kriboogh commentedI was looking at the code in the current patch here... like I said in the comment that Anybody was referring to in #3, I still feel like this patch is the wrong way forward. Yes, it fixes your site, but not in a good way. Default config in drupal needs to be fixed to English, even if your site is just installed with a single other language. It would solve so many issues currently in core regarding config (overrides). Not the other way around where we now have English configs that are directly forced into a translation by setting the langcode to the default language and translating the values. I know my comment isn't constructive, I don't have a direct solution myself, just expressing what I think should be done in core. Forcing all config to be English by default probably involves a lot of fixes in core, specially where config is currently being exposed to the user in forms and default values are set using the current interface language and as a result saved again in default config having a different langcode and using the wrong translated values.
Comment #18
anybodyHuge +1 on #17 from our side! That's the only clever long-term solution!
Comment #19
kingdutchI can only add on to the "can we standardise on English as default config language and remove the ability to change that". I am sensitive to the fact that it likely removes the ability for people to develop in a different language than English. However, English is already the standard for core and contrib, so in practice that's already quite difficult.
Over the years we have had multiple sites where unfortunately during a set-up process someone had switched the site default language because the default shouldn't be English. However, this creates tremendous maintenance issues because the same code (e.g. "update this config value if it matches something else") behaves differently in different environments.
We're now resorting to removing the ability to change a language on
/admin/config/regional/languageand to remove the ability to delete English as a language. We have other modules in place that deal with language detection and selection and that hide English from users. Any other way to try and run a multi-lingual site seems to be a footgun for every person new to Drupal.It's possible that the stop-gap of "we won't let you make the same mistake again" by taking away some flexibility should be split out from this issue which seems to be more focused on "we'd like to fix all the things we accidentally broke".
Comment #20
borisson_We need to find a good direction, so tagging this for framework maintainer to see what the best path forwards is here. I think I agree with @kriboogh in #17 - and it's what I try to do on all my projects as well.
Comment #21
berdirI understand that in many scenarios, especially larger, complex multilingual worked on by agencies, this is beneficial, but this is a very far-reaching change and a very complex problem space. We have some sites were we also have some guardrails in place and only creating config entities in EN, but many others we do not.
Configuration is not just created by administrators. Take webforms as example. webforms may be created by editors and similar user roles, and sometimes those webforms are for specific languages only and are created only for those. Multi-region/country sites may have editors that only speak their native language.
It's worth pointing out that the config system kind of used to work like that, before 8.0.0. But it was inconsistent/buggy and single-language sites then resulted in config being stored in language overrides which then were not editable through the UI at all. I pushed for this change then.
Non-English but single-language sites are common, how is this supposed to work for them? Would these sites operate on purpose in a mixed mode where they edit *with* overrides? Sometimes sites start as non-English and then add other languages, including English, what would the default config contain as translatable strings?
I'm not sure what the answer is either. Maybe we need to have this as an option that can be enabled as a setting or something? Either way, we need to make sure that all possible scenarios are accounted for whatever change we make.
Comment #22
jose reyero commentedHi, I've just seen this issue and, having been working on many similar and related issues for some years, I want to add some thoughts.
I mostly agree with @berdir here, we need to keep the ability to maintain non-English Drupal sites without extra overhead, but also we need some consistent solution for language and configuration management, that is currently a mess - for which I'm partly responsible btw :/ .
The main issue IMHO is that, even if we have the same languages enabled, for the exact same configuration, we are switching the storage back and forth depending on which the default language is. Why don't we try to find a way to just **keep the storage consistent**, and then allow the user to switch the default language anytime. That should affect how the UI works - including the configuration and translation UI - but not how the config is stored.
How? Well, not so sure about this, may need more thinking and work, but my first idea is: Let's move from 'Default config' to 'Base config'.
1. Store the common language-less configuration separated in the base directory (That would be 'Base config')
2. Store all the translatable stuff as per-language configuration - including English strings - like.. languages/LANG/config.yml ?
Then:
* When installing modules' configuration, create the base config, move English strings to languages/en and create any other translations if available on their corresponding place.
* When creating configuration using the UI, same but it won't have English version just languages/xx/ version, depending on the default or the language that was used.
The 'Base configuration' may still have some default 'lang' but that only means the language that was used to create it and will just determine the overriding order, something like this:
- For installed config - lang=en, load the base config + English + current language (which may be available or not)
- For created config - lang=xx, load the base config + xx + current language
And yes, we need to always keep "English" somehow, just because the installed configuration comes in English. But it doesn't mean it needs to be enabled for the site navigation. Maybe it can be "defined", but "not enabled" (?).
Then you can enable / disable / switch languages, whatever, the configuration just stays the same. Still, we can provide some tooling to purge old/unused languages from configuration...
Comment #23
anybodyWhao, thank you very very much for your highly valuable feedback @jose reyero!
I very much agree on many of these points and suggestions. That sounds like a wonderful plan and would resolve many of the user-facing and developer-facing issues, I think.
Comment #24
kriboogh commentedI don't think there would be a great overhead though to make this work. And what you describe pretty much also what my initial idea was of having default (or base as you call it) config always as english. When you install another language, you just add a (translated) copy of that config as a language.xx collection. That way it doesn't matter if english is "installed" or not, or which language is "default". The config system would just fetch the currently needed language configs and if it can't find it use the config from the default language collection, and if it can't find that use the base english config.
Comment #25
gábor hojtsyThe title of the issue is "Convert / unify all default configs to the site default language" which is already the goal of Drupal. It just happens that if you change the site default language that unification does not run. It runs when you then install a module. That's a bug and that is at #3337864: Introduce a dedicated "Configuration default language" different from "Site default language".
The flow explained the issue summary is a symptom of that bug. If at the time of changing the site default language all of the default language of all config would be swapped over, that would make this a non-issue IMHO. That swapping over already happens when you install a module so we "just" need to do the same swapping when you change the site default language, so it does not suddenly happen later at a "random time".
Then this issue was steered towards English as a default. Joining @berdir and @Jose the feature to have config in your active site in non-English by default is because a lot of sites are not English by default. You have a French site, all of the content and config is in French, your menus are French, etc. Why would you have English as the config of your views and content types, etc. Why would you need to go to entire different translation UIs to "translate" them when you never use them in English? Why would you need to create new content types and views in English and then translate them to French?
@Jose's idea is a whole rearchitecture of how config is stored/managed, it would need a lot of syncing to be sure the structure is consistent when eg. you add a views display some parts would appear in the language-less config and some parts in the language config and when merged they need to give out a coherent whole. I don't think we should invest in that but others may feel stronger :)
I do think we need to fix #3337864: Introduce a dedicated "Configuration default language" different from "Site default language" properly by running what will run later when installing a module anyway. Closing as duplicate of that one.
PS config_translation is a UI for editing config translation, it does not actually manage configuration language, so putting this update there would have been misguided.
Comment #27
anybodyThank you VERY VERY MUCH @gábor hojtsy for your wonderful feedback and background-knowledge and replying here!
Comment #28
gábor hojtsyIronically #3337864: Introduce a dedicated "Configuration default language" different from "Site default language" moved to basically implement the title of this issue :D That also had various contributors and history, so let's all unify there shall we? :)