Problem/Motivation
When using Altcha on a multilingual site the translations are missing.
Steps to reproduce
Install Altcha module and change language on Drupal.
Proposed resolution
Detect the interface language and add the i18n file for the detected language from Altcha distribution.
I suggest we also provide an option to use a custom JS file that uses Drupal.t. That way you can select between Altcha bundles translations and custom translations from Drupal's own translation engine.
Of course, you'd still be able to override strings but this would at least provide a substantial amount of localisation out of the box. And this module could even provide its own translations above and beyond Altcha under the "custom" translation option.
Remaining tasks
1. New configuration option to select Internationalisation method: "Altcha" / "Drupal"
2. Set the language code on the widget using Drupal's own language code to take precedence over the browser/HTML element language
3. Altcha mode: Attach to the page the correct matching i18n JS file for the current Drupal language, matching first on full code then on the prefix
4. Drupal mode: Set language on the widget to "custom" and attach a custom i18n JS file that registers "custom" as a language with Drupal.t phrases that can then be overridden in Drupal's regional settings on a per language basis
The strings settings remains to override if needed.
User interface changes
-
API changes
-
Data model changes
-
Issue fork altcha-3607033
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
Comment #2
driskell commentedComment #3
robindh commentedThanks for writing this out, it would be great to support all these translations out of the box. I agree with most of the implementation, except for the part where only the i18n file of the matching language is attached. This implies we need to package every language separately in the module, which will make it hard to maintain whenever there's an update.
I think the footprint of the "all" version (e.g. https://cdn.jsdelivr.net/gh/altcha-org/altcha/dist/i18n/all.min.js) is small enough to just include this version and to protect maintainability. Users can also opt-out of this completely by providing their own translations via "drupal" mode, as you suggested.
Another small task would be to add an extra check in
altcha_local_tasks_alter, we probably don't want the 'Translate ALTCHA' local task to be shown when using altcha mode. This could be confusing for usersComment #4
driskell commentedComment #5
driskell commentedThanks! I'll hopefully get this sorted in the next week.
I agree with you - I did initially (in a draft POC) do the full list of languages as separate files and indeed that's why I wanted to reach out - it is a lot of files... and you're quite right the all.js is likely better balance for maintainability especially if there's a mode to attach a minimal file that utilises Drupal's translation engine.
Comment #7
driskell commentedHi @robindh
I realised an issue when testing and maybe it was just me - the mixture of async+defer as I understand means defer just gets ignored and it ends up async. The problem with async is there is no defined ordering. So there's no guarantee the JS runs before the dependency libraries (altcha/altcha as an example) as even if the dependencies are non-async and non-defer, there is no guarantee they download first. Using defer on its own would guarantee the ordering though I think. I did also note in my case it wasn't appearing in the header even though true as the libraries depend on others which appear in the footer. I dropped both async and defer statements for now as I wondered what you thought on that.
I also maintained the "Translate altcha" as that's not us it's the configuration translation module that is allowing you to translate the labels. Those labels are still technically viable and useful as they'll let you CHANGE the English translation and I'm not sure that's easy with the interface translation. So there'll be two methods to do Drupal based translation - override the English and then translate those overrides for each language - or don't override them and use Drupal's user interface translation area to change or add the translations. I'll be honest in that if we wanted to simplify things - perhaps we just drop the Drupal.t method... and just load the all.js but let people override and translate with config translation instead... (which IIRC, might actually still pull in values from user interface translation if not explicitly translated in the configuration...)
In summary:
- No header:true, no async, no defer, as we depend on Drupal.behavior and Drupal.t that only get added in the footer and we want to register before altcha loads.
- Added the all.js library
- Added a Drupal.t powered custom library
- Added the method to select between the two methods
- Added override URL for the i18n all.js library
Maybe there's one more option too which is to not install all.js if the default language is "en" and there's only 1 language?
If we remove the Drupal.t method I can make it a toggle "Load ALTCHA i18n translations" yes/no.
Thanks
Comment #8
robindh commentedThanks; did a quick first test and added remarks to the merge request.
Some feedback on the previous comment:
- I do think we'll need to look into the
deferandasyncattribute changes since the ALTCHA docs recommend using these- Agree on retaining the "Translate altcha" tab, so the overrides can be translated
- Not attaching the all.js file when the only language on the site is EN seems like a good optimalisation as well
We'll also need some additional automated tests. The most important ones are checking the i18n library override (similar to the other override tests) and checking whether the label overrides are actually applied to the widget in both ALTCHA and drupal modes
Comment #9
driskell commented@robindh I think I've covered all the needed changes, and added tests. I used AI to help write those tests based on the existing tests and they look good to me.
Comment #10
robindh commentedThanks, made some more tweaks to the merge request:
- Removed async from altcha-main & -obfuscate scripts: noticed some loading order issues while testing as well
- Restructured the settings form
- Drupal translations are now passed via drupalSettings, relying on config translation system to fetch translated values. Mainly because we don't need to keep Drupal.t strings in sync whenever altcha introduces new string values. This means we can just pass the config values along via drupalSettings without duplicating them in a Drupal.t definition
- Removed the strings attribute from the altcha widget, relying only on custom-translation / altcha i18n scripts to alter the widget strings. This will make it easier to port to altcha v3, where the strings attribute is not supported anymore.
- Added similar i18n support for the obfuscate formatters
- Reworked the custom translation script to avoid needing the "minified" initialization part
- Added remapping of regional langcodes (e.g. "fr" -> "fr-fr")
- Added extra test coverage
Will do some more regression testing tomorrow, but the merge request should be pretty complete by now
Comment #11
driskell commentedI added a comment about the lang codes as I don't think you need to map "fr" to "fr-fr" - Altcha handles it fine.
I like the new label handling, that is a good approach that keeps BC :) That one was a conundrum to me and it looks clean now. Thanks!
Comment #13
jeremy.declerckI tested this and everything was working great!
I only got confused with the wording of the 'i18n_method' labels and description.
It showed either
- ALTCHA i18n JS library
- Drupal interface translations
Which made it look that Drupal interface translation overrides would only work when selecting the bottom option. But overrides work in both scenarios. I tried to simplify the text a little bit to make it more accessible.
Comment #16
robindh commentedThanks for the efforts on this feature! Committed to 1.x and 2.x. Will start work to make the v3 issue compatible with this feature as well
Comment #18
driskell commentedAmazing! Thanks @robindh, really appreciate your time.
If you're able to - I'd like to help finish the AJAX support too - I'm already running it and it works for Webforms and there's a test on it too for a standard Ajax submit form: https://www.drupal.org/project/altcha/issues/3484543