This is a whole proposal for implementing Context and Plug-ins into the configuration system, that would allow among many other things, adding localization plug-ins for the configuration. The main ideas are:

- Extremely simple API for modules to use/create configuration values as everything will be handled by plug-ins and contextual values. Basically the API stays the same as current: config('system.settings')->get('variablename');
- Introduces a Configuration Context (ConfigContext) object that will hold all the 'contextual' data related to a Configuration object (like language, domain or country, just some examples). A configuration object will be linked to a context.
- Languages will be handled by the localization system being a generic ‘Configuration Plug-in’. The config system will provide enough hooks for modules to react on configuration loading / saving and also for altering runtime values depending on 'context'.
- We need metadata about configuration values (hook_config_info?) but only for initial loading and storing of configuration. That metadata must not be needed at run-time.
- The configuration system will handle low level loading and storage, also for special configuration files for arbitrary 'realms' or 'domains', though it doesn't need to be language aware.

Remaining tasks

1. Metadata, #1648930: Introduce configuration schema and use for translation
2. Contextual configuration, #1763640: Introduce config context to make original config and different overrides accessible

The whole proposal is documented here
https://docs.google.com/document/d/1REis8ZUnRkebkMVHu_TXJlhDEBZgcBHNIhkJ...

Files: 
CommentFileSizeAuthor
#5 config-plugins-01.patch43.35 KBJose Reyero
FAILED: [[SimpleTest]]: [MySQL] Failed to run tests: PHP Fatal error encountered during run_tests.sh. See review log for details.. View

Comments

Gábor Hojtsy’s picture

Title: Translatable configuration (with Context and Plug-ins) » Multilingual/translatable configuration with Context and Plug-ins [OPTION B]
Issue tags: +sprint

Putting on the sprint and retitling to tie up with #1613350: Multlingual/translatable configuration [OPTION A] which is OPTION A.

Jose Reyero’s picture

Issue summary: View changes

Updated issue summary.

neclimdul’s picture

I'm having trouble reading this because the term plugin has gained a lot of meaning and I don't think what you are saying is actually using that #1497366: Introduce Plugin System to Core.

So, I do have one quick observation. The syntax of requesting config from a object like this seems pretty convenient. However, wouldn't it make more sense to use the DI Container in core? Since the language contextual information is already being built into the DI Container, and it already has /more/ context then an entirely new system and can be defaulted back it provides a strong starting place and should require less changes to CMI. Also, "context" as a term has a really bad problem that makes it a red flag for me. It only makes sense in a context.

I've not been working on CMI for a while so I'm going to write this off the cuff and with minimal thought put into it but it could possibly work something like this:

// Get config with the default/current language.
$value1 = config()->get('mymodule.value1');

// Fetch some config with a different language.
$di = drupal_container();
/*switch languages*/
$value_language2 = config($di)->get('mymodule.value1');

// Fetch several config values from a different language.
$language_config = config($di);
$value2 = $language_config->get('mymodule.value2');
$value3 = $language_config->get('mymodule.value3');
Jose Reyero’s picture

> the term plugin has gained a lot of meaning and I don't think what you are saying is actually using that

Right, same with 'Context' and many other things, so yes, we should be using those when ready.

> wouldn't it make more sense to use the DI Container in core?

Right again. Actually latest version is using DI and Containers.

Anyway I'd say these are just implementation details, I'd rather discuss the actual architecture (which of course will be using as much of the other APIs as is possible later).

Jose Reyero’s picture

FileSize
43.35 KB
FAILED: [[SimpleTest]]: [MySQL] Failed to run tests: PHP Fatal error encountered during run_tests.sh. See review log for details.. View

This is the full patch, including also some example config files (book, system.site_information) to see how it would look like.

There's also a module here using this API for manual testing and development, that prints out some multilingual variables in several languages, http://drupal.org/sandbox/reyero/1635230

neclimdul’s picture

Anyway I'd say these are just implementation details, I'd rather discuss the actual architecture (which of course will be using as much of the other APIs as is possible later).

I thought I was. I was suggesting not making another context system entirely. I just skimmed your patch but it looks like you have made a separate context system and just placed it on the global container. I'm still not seeing the reason for this. I'll try to make some time to make a deeper review and confirm this.

tstoeckler’s picture

Status: Active » Needs review
+++ b/core/includes/config.inc
@@ -46,13 +103,25 @@ function config_install_default_config($module) {
+      if (strpos($last, CONFIG_REALM_MARK)) {

Unless this intentionally wants to wail on something like $last = '=abc'; (which might very well be, I don't know), this should be if (strpos($last, CONFIG_REAM_MARK) !== FALSE) {. If this is intentional, we should probably add a comment.

tstoeckler’s picture

Status: Needs review » Active

Oops, didn't want to change status, thought this was at "needs review" already. (Sorry, testbot...)

neclimdul’s picture

Looking at this now. Trivial reviews first:

d8 ±8.x✗ » git apply config-plugins-01.patch                                                                                                                                      1 config-plugins-01.patch:859: new blank line at EOF.
+
config-plugins-01.patch:1014: new blank line at EOF.
+
config-plugins-01.patch:1227: new blank line at EOF.
+
config-plugins-01.patch:1340: new blank line at EOF.
+
config-plugins-01.patch:1360: new blank line at EOF.
+
warning: 5 lines add whitespace errors.

Is there a test(simpletest) to demonstrate what's being achieved?

neclimdul’s picture

Status: Active » Needs work

First pass:

+++ b/core/includes/config.incundefined
@@ -82,7 +151,181 @@ function config_get_storage_names_with_prefix($prefix = '') {
+  try {
+    return drupal_container()->get('config.context.' . $type);
+  }
+  catch (InvalidArgumentException $e) {
+    $context = config_context(array(), $type);
+    drupal_container()->set('config.context.' . $type, $context);
+    return $context;

This sort of lazy loading could just happen as a factory on the DI container.

+++ b/core/includes/config.incundefined
@@ -82,7 +151,181 @@ function config_get_storage_names_with_prefix($prefix = '') {
+
+/**
+ * Get container of configuration plug-ins.
+ */
+function config_plugin_container() {
+  try {
+    return drupal_container()->get('config.plugin');
+  }
+  catch (InvalidArgumentException $e) {
+    drupal_container()->register('config.plugin', 'Symfony\Component\DependencyInjection\ContainerBuilder');
+    return drupal_container()->get('config.plugin');
+  }

The container already does lazy loading. This should go away and the service should be registered in the initialization bootstrap.

Also, as I said before we already have a plugin system and this very different. If you're going to go this route lets call it something different.

+++ b/core/includes/config.incundefined
@@ -82,7 +151,181 @@ function config_get_storage_names_with_prefix($prefix = '') {
+  $container = config_plugin_container();
+  foreach ($container->getServiceIds() as $id) {

I'm not seeing where the definitions are set for the container.

+++ b/core/lib/Drupal/Core/Config/ConfigContextInterface.phpundefined
@@ -0,0 +1,47 @@
+ * - Global / Static, it is the same object always for the same configuration
+ * type, it can be created and retrieved by using config_static_context()
+ * - Custom. To be used by pieces of code that get configuration with specific
+ * parameters (user, language, etc...). It is created every time we invoke

This sounds like the same information that we're putting in the container. Can you help me understand how its different?

Realm is really confusing. Maybe its the right term but its lightly documented and has me thinking access control not language.

Gábor Hojtsy’s picture

As per our discussion in Barcelona with heyrocker (CMI), webchick (core), merlinofchaos (views), reyero (i18n), webflo (i18nviews), Gábor Hojtsy (D8MI), xjm (views) and others, we are going with a base implementation of this option for now. In short we figured out we have a need for almost anything to be translatable/multilingual, we need some context information passed around and we need to make the system extensible due to the definite lack of time to solve all problems until code freeze, and all of those criteria lead us to work with this option. Let's focus our efforts on getting it done best!

Jose Reyero’s picture

While waiting for some config system rework and plugin system to land, we are splitting this patch in several smaller tasks and trying to make progress with them. Only for the first one (metadata) the path seeems to be clean as it doesn't depend on any of the others. For the rest we may need to wait a bit more before they become clean patches against Drupal HEAD.

#1648930: Introduce configuration schema and use for translation
#1646580: Implement Config Events and Listeners, and storage realms for localized configuration

Dependencies:
#1626584: Combine configuration system changes to verify they are compatible
#1497366: Introduce Plugin System to Core

Gábor Hojtsy’s picture

Title: Multilingual/translatable configuration with Context and Plug-ins [OPTION B] » Implement multilingual configuration with plugins and context
Priority: Normal » Critical

Retitling to be more specific to current thinking and remove option B signage so it is clear this is the route we are taking. Elevating to critical as per #1448330: [META] Discuss internationalization of configuration being marked fixed, and needing to carry over the requirement to the implementation issue to ensure completeness.

Gábor Hojtsy’s picture

Issue tags: +language-config

Add language config tag too.

neclimdul’s picture

Title: Implement multilingual configuration with plugins and context » Implement multilingual configuration with plugins and DI

Awesome thanks for the update.

As I said earlier, I'll advise against using the term "context" because it never means the same thing and always encompasses too many concepts. That's an important reason WSCCI stopped using the term in discussions and just refers to objects that have contextual information(our service container, the request object, the response object, etc). From my understanding of what is being written, we're talking about services registered on the Drupal container, objects from plugins and possibly stand alone and dependency injection. I'm actually not seeing the plugins yet but I trust they're there. They pop up all over.

Jose Reyero’s picture

@neclimdul,

Agree about the term 'context' (which is already causing trouble and misunderstandings). Also 'plugins' may not be the kind of plugins (configurable, etc) they are talking about on the other tasks.

Any suggestion for renaming them?

About plugins, yes, they're implemented, though this are hardcoded plugins injected by modules so I guess they won't map on our 'generic plugin architecture'. Looking for an alternate name too.

It seems we need a namespace for these concepts too :-)

Gábor Hojtsy’s picture

I've read up on the google doc linked from the summary and looked at the patch in light of our discussion last week in Barcelona. First it would be great to (a) update the doc with the current ways of thinking (b) paste the thing into the summary instead of having it all in a google doc. I know it is long and full of examples, but if we can find ways to keep it short and sweet and put it all here, that would help us get feedback.

As per my personal recollection we also discussed we are going with a "slimmed down" context/plugins approach to have enough implementation that will carry us to solutions but waiting to integrate with progress in that space in Drupal 8 instead of reinventing the wheel. That sounded like would result in some changes in the approach as well, like not actually getting the config from a context (but the DI container?).

All-in-all it would be great to have an up-to-date write-up. I likely did not pay enough focused attention to be able to do that writeup, I've had all kinds of other sprinters to help make progress all the time, so it would be great if you could do it soon @reyero. We should hopefully figure out how to stage the inclusion of this so it does not take months to debate :) You've got it absolutely right at first that it needs a well written writeup. Now to keep it up to date :)

Thanks again for your work!

Kristen Pol’s picture

Title: Implement multilingual configuration with plugins and DI » Implement multilingual configuration with plugins and Dependency Injection (DI)
Jose Reyero’s picture

Now some major config rework that was blocking every other change has been committed, we can start moving with small patches.

@Gábor
Right, I will be updating the doc (and making it shorter) and updating the summary at the top of this issue.

First patch (config overrides) in config object, awaiting review, see #1671198: Merge $conf overrides only once per instantiated Config object, and move initial setName() into Config constructor

Jose Reyero’s picture

Updated patch against latest 8.x, also simplified it a lot (and btw renaming plugins to Config Helpers), this one needs review too: #1646580: Implement Config Events and Listeners, and storage realms for localized configuration

Gábor Hojtsy’s picture

Forgot to attach the new patch?

Jose Reyero’s picture

That was not the 'big patch', just one more part and is attached in the other issue.

Recap of small patches in queue:
#1671198: Merge $conf overrides only once per instantiated Config object, and move initial setName() into Config constructor
#1648930: Introduce configuration schema and use for translation
#1646580: Implement Config Events and Listeners, and storage realms for localized configuration
This is a module to demo the patches features, add some config translations, etc
http://drupal.org/sandbox/reyero/1635230

I still need to work out the 'Context' concept again after some big config rework that got committed and then post the full big patch to this thread.

sun’s picture

Category: task » feature
Gábor Hojtsy’s picture

Title: Implement multilingual configuration with plugins and Dependency Injection (DI) » META: Implement multilingual CMI

The underlying technologies (DI, context, helpers, plugins, etc) are being debated in the sub-issues now, so rename just as an umbrella issue.

Gábor Hojtsy’s picture

Big news:

- #1646580: Implement Config Events and Listeners, and storage realms for localized configuration was committed, allowing us to store language specific values for CMI key, yay!
- #1668820: Concept, base class, and interface for Configurables (e.g., node types, image styles, vocabularies, views, etc) is also committed, and it will have API implications on how we translate thingies

Ongoing issues:

- #1648930: Introduce configuration schema and use for translation

(don't know of other specifics at the moment, should ask @reyero to update).

Jose Reyero’s picture

Status update. Since we already have configuration overrides and event listeners, we are halfway there. The two other pieces we need to get on the configuration side are:

1. Metadata, #1648930: Introduce configuration schema and use for translation
2. Contextual configuration, #1763640: Introduce config context to make original config and different overrides accessible

I don't think the 'Configuration Thingies' patch will be that important for this purpose. What we need more urgently is some 'translatable' configuration to work with, these ones should be useful:
- #1757566: Convert user account e-mail templates to configuration system
- #1588422: Convert contact categories to configuration system

Then, on the locale side I'll be creating an issue for the import/update/translate workflow for configuration strings.

Gábor Hojtsy’s picture

Issue tags: -sprint +D8MI-meta

Tagging with D8MI meta tag instead of just vanilla D8MI.

Jose Reyero’s picture

Translation workflow for config strings, first try, is in queue, #1777070: Refactor and clean up source string location handling

Jose Reyero’s picture

Issue summary: View changes

Updated issue summary.

effulgentsia’s picture

This issue hasn't had activity in 5 months, but is prioritized critical. Is it still a useful issue, or is there a newer issue tracking what's left to do here?

Gábor Hojtsy’s picture

@effulgentsia: the base metadata system is in, however there is *no* multilingual aspect to it yet. We can consider that an integration issue now that the schema format is in, if we want to (#1905152: Integrate config schema with locale, so shipped configuration is translated). There is also still #1763640: Introduce config context to make original config and different overrides accessible that is still bouncing around between different ideas as (a) hard to find people to work on it (b) people cannot agree.

So I don't think this is fixed at all. We can choose to elevate the others to higher levels if we want to do that and close down this issue if that is preferred.

webchick’s picture

#1763640: Introduce config context to make original config and different overrides accessible is now fixed, so if #1905152: Integrate config schema with locale, so shipped configuration is translated is the last piece of this puzzle, I'd say let's close this as a dupe and escalate that one to critical. Or did I misread #31?

Gábor Hojtsy’s picture

Status: Needs work » Closed (duplicate)

Agreed, I meant to do it yesterday.

Gábor Hojtsy’s picture

Issue summary: View changes

Updated issue summary.