backdrop / backdrop-issues

Issue tracker for Backdrop core.
145 stars 40 forks source link

Alternative approach to translating config, using get/set #3522

Open herbdool opened 5 years ago

herbdool commented 5 years ago

From @sthomen. Moving from https://github.com/backdrop/backdrop-issues/issues/704 because it's closed and proposes a very different approach to translating config:

I'm probably not expressing myself properly, the idea was to make something like this: https://www.youtube.com/watch?v=p-1z72YgPCc

In this example video there is no change to the site settings code. It uses the standard language selector block in the admin layout. The only difference is a little special handling in config.inc. Now this is a very crude thing I cooked up this afternoon, and calling the new method setLangcode in get() and set() is probably suboptimal, but it works and it's easy to make configuration strings translatable and it should make it much easier for end users to find them.

There could perhaps be a separate UI page for converting strings to be translatable, drupal8 does something like that I think. Profile builders, module builders could easily bundle translations with their default configs.

Perhaps I'm totally out sailing, but isn't this a better approach than going via t() and also having a configuration setting?

system.core.json looks like this:


"site_name": {
"_translated": true,
"sv": "Test sajt",
"en": "Test site"
},

[...]

"site_slogan": {
    "_translated": true,
    "sv": "Detta är ett häftigt test!",
    "en": "This is a test."
},

>Here's a zip with my changes:  [translatable_config.zip](https://github.com/backdrop/backdrop-issues/files/2825533/translatable_config.zip)
herbdool commented 5 years ago

Hi @sthomen, I've been thinking of how to be explicit on the choices that were made thus far and why. If you read the entire thread https://github.com/backdrop/backdrop-issues/issues/704 it'll help quite a bit in understanding how this developed. But I've tried to make them into bullet points here. The criteria:

So your alternative approach needs to be able to address at least these concerns (there may be others). And it needs to be compelling enough to convince Backdrop core maintainers to revert the work already put into core, if that's possible.

sthomen commented 5 years ago

I've been very busy and haven't had any time for backdrop so thank you so much for giving my shower idea so much effort, @herbdool!

sthomen commented 5 years ago

I had some time this morning and put together a branch with my proposed changes here. It really is just the changes to config.inc so far.

This configuration translation is modelled on what I remember from trying drupal8 (not actually reading their code), so the ideas come from there via my terrible memory.

Backwards compatibility This is perfectly backwards compatible, any configuration key that hasn't been converted to a translatable version will work just like before, meaning no changes will be required; it merely set up the ability to handle configuration values with multiple translations. No attempt will be made to save new translation values unless the value is marked as being translatable, in which case the current language settings (via $config->langcode and $config->setLangcode()) are used to determine which translation to save.

Note that the determination of what is a translatable configuration key is made at the point of get/set, meaning that the value has to be converted before it is treated as a translated value and filtered/merged.

Translations via locale.backdropcms.org That translators should be able to provide values via potx seems to be very tied to the idea of using t() for translations. While it might be nice to get ready-baked translations, this isn't the goal of configuration is it? We're dealing with configuration values that the site builder will likely set/change anyway; rarely does anyone want a general translation for the site slogan. For things like confirmation emails from an embedded webstore it gets more into a gray zone and I don't have a good aswer for that. This at least makes it possible to translate them without maintaining local patches because the original developer of critical module X disappeared!

Minimize needs for a different translation system Minimalism is my entire goal here, by handling translatable values in config, we do not need to change anything else in backdrop, the correct translations are served up/saved as needed.

Setting the language returned As for the edge case of _user_mail_text(), you can set the language to retrieve at any point, just use $config->setLangcode() and any value retrieved after that will use that translation. This kind of breaks my idea of not having to modify callers, but it most certainly is possible.

Caveats and problems Right now, a value can only be set as translated by manually editing the JSON configuration files to reflect the right structure, which is kind of suboptimal. One idea to deal with this is a huge form that lets you bulk convert strings (a checkbox for each leaf value in essence), and that doesn't seem very user friendly. Maybe some kind of search function like the regular translation interface. ISTR that drupal8 has a list with friendly names and descriptions of what to enable translation for, but this would require having those names pegged to configuration variables that it makes sense to translate somewhere.

Another (minor?) issue is that as a site builder, you can't tell from the input form that any given value is translatable. I don't think this would truly be a problem though. When creating the site they notice, oh that value didn't change perhaps I forgot to enable translation for it.

Unit tests are needed and I am still trying to get into writing test.

herbdool commented 5 years ago

Thanks @sthomen.

Here's a link to a diff of your branch to the official: https://github.com/backdrop/backdrop/compare/1.x...sthomen:config-translation.

I'm going to consider your points but I also think @quicksketch will have a more informed look and response.

herbdool commented 5 years ago

From what I can tell, even in Drupal 8, configuration can be localized in locale.drupal.org. https://www.drupal.org/project/potx/issues/1933988. I could be misunderstanding what I can see from the link.

sthomen commented 5 years ago

I installed drupal 8 and had a look around, and the way they do things are very different from my implementation. Translatable strings are identified via a type variable in a configuration schema and when pulled from the database into a "sync" bundle, the translated strings are stored in a separate directory, with identical files but different values (of course). In the database the config table has a "collection" column that identifies language specific values--makes me think of i18n variables from drupal 7. The actual values are all serialized blobs, yuck.

The type of the value has handlers associated with it (I didn't look too closely at the schema stuff), but the key thing is that these are overridden by the config_translation module and it then handles the translation things. It's all very convoluted and enterprisey like the rest of drupal 8.

Going back to backdrop; because my translation system is dynamic--any leaf node can be translated--how would potx know what string to extract? It could use the _translated key to find leaves that have been set as translatable and export those. The other way should be simpler; when importing a translation, convert the value to be translatable and set(). A context comment with the string could contain the key "path".

Anyway, it's past midnight and I'm probably rambling... better stop. 😴