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

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

driskell created an issue. See original summary.

driskell’s picture

Issue summary: View changes
robindh’s picture

Thanks 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 users

driskell’s picture

Assigned: Unassigned » driskell
driskell’s picture

Thanks! 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.

driskell’s picture

Hi @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

robindh’s picture

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

Thanks; 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 defer and async attribute 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

driskell’s picture

Status: Needs work » Needs review

@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.

robindh’s picture

Issue tags: -Needs tests

Thanks, 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

driskell’s picture

I 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!

jeremy.declerck made their first commit to this issue’s fork.

jeremy.declerck’s picture

I 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.

  • robindh committed a727dda4 on 1.0.x authored by driskell
    feat: #3607033 Missing translations
    
    By: driskell
    By: robindh
    By: jeremy...

  • robindh committed 8b5e184e on 2.0.x authored by driskell
    feat: #3607033 Missing translations
    
    By: driskell
    By: robindh
    By: jeremy...
robindh’s picture

Assigned: driskell » Unassigned
Status: Needs review » Fixed

Thanks 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

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

driskell’s picture

Amazing! 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

Status: Fixed » Closed (fixed)

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