Problem/Motivation

Follow-up for #3202664: CKEditor 5's UI language should match Drupal's interface translation to provide API for contrib projects to load CKEditor translations. This requires identifying which translation files exist, an associating them to the related library. Once the translation file is associated to the correct library, CKEditor 5 module is able to load the correct translation files based on the current UI language.

Proposed resolution

CKEditor 5 plugins needs to be compiled with the DLL build to be able to work with Drupal. This build automatically adds translations to the translations/ subdirectory. This is predicable because the original .po files used in the translation process are in a lang/translations/ sub-directory by convention.

The expected directory structure of a DLL build is the following:

ckeditor-plugin-name/
  - translations/
  - ckeditor-plugin-name.js

The only thing needed from contrib author is to declare that a plugin has translations and it can be done by adding a dependency to the core/ckeditor5.translations library in their plugin library declaration. Then Drupal will automatically find and load translations files.

myDrupalCkeditorPlugin:
  js: 
    assets/js/ckeditor5/ckeditor-plugin-name/ckeditor-plugin-name.js: { minified: true, preprocess: false }
  dependencies:
    - core/ckeditor5
    - core/ckeditor5.translations

With this declaration will automatically look for translations in the assets/js/ckeditor5/ckeditor-plugin-name/translations/* folder.

Remaining tasks

User interface changes

API changes

Data model changes

Issue fork drupal-3228464

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

lauriii created an issue. See original summary.

Wim Leers credited Reinmar.

wim leers’s picture

Just discussed with @Reinmar; there is no standardization around CKEditor 5 plugin development, and therefore also no standardization around directory structures either, including for example translations.

They actually just started looking into that!

wim leers’s picture

Title: API for contrib projects to load CKEditor translations » [upstream] API for contrib projects to load CKEditor translations
Status: Active » Postponed
Issue tags: +Needs upstream feature

We should wait adding this until they've standardized it.

wim leers’s picture

Project: CKEditor 5 » Drupal core
Version: 1.0.x-dev » 9.3.x-dev
Component: Code » ckeditor5.module

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

wim leers’s picture

Assigned: Unassigned » bnjmnm
Status: Postponed » Active

Per @Reinmar: Recently https://github.com/ckeditor/ckeditor5-package-generator got explicit support for translations, so this should work fine now.

See https://ckeditor.com/docs/ckeditor5/latest/framework/guides/plugins/pack... + https://ckeditor.com/docs/ckeditor5/latest/framework/guides/plugins/pack...

We should verify this ASAP, so we can either confirm this is working and finish this issue, or report what is not working.


Assigning this to @bnjmnm because he built https://git.drupalcode.org/project/ckeditor5_dev/-/tree/1.0.x/ckeditor5_..., and I think that makes him the best positioned person to take a critical look at this 🤓

@bnjmnm, @Reinmar told me you should reach out to him prior to starting on this, because he thinks the docs at https://ckeditor.com/docs/ckeditor5/latest/framework/guides/plugins/pack... are not complete enough for you to get a good start on this!

wim leers’s picture

Issue tags: +stable blocker
lauriii’s picture

Assigned: bnjmnm » Unassigned

I'm not convinced that the ckeditor5-package-generator would help with solving this problem. It seems like the tooling is helping plugins to load translations from Transifex. However, what we need is an ability for contrib modules to load pre-built translation files.

At the moment, we generate libraries for translations automatically in ckeditor5_library_info_alter. These libraries are then loaded dynamically depending on the current UI language in \Drupal\ckeditor5\Plugin\Editor\CKEditor5::getLibraries. We need an API that provides equivalent functionality to contrib.

I think the information that is needed is the directory where the translation files are located, and based on that CKEditor 5 module could handle generating libraries and then loading them later when needed.

lauriii’s picture

Title: [upstream] API for contrib projects to load CKEditor translations » API for contrib projects to load CKEditor translations
Issue tags: -Needs upstream feature

I think this is something that will have to be done on our side, unless CKEditor provides a new API that handles the discovery and loading of translations.

lauriii’s picture

I guess there's a second part which could potentially be relevant to contrib projects which is that we have a script in core/scripts/js/assets.js that collects and concatenates translations from different plugins.

Since it's discouraged for contrib projects to include 3rd party libraries, they will likely follow approach where they either use libraries system, or provide an intermediate package in Github that can be loaded using composer.

For either of these use cases it seems unlikely that the script would be useful. With the libraries system approach, they wouldn't want require users to run the script and with the composer approach they would likely have one repository per plugin.

I guess what is needed is documentation on what is the expected structure so that module authors can evaluate if the plugin they are integrating with is compatible with that. If the plugin isn't compatible, they will either have to provide integration themself, or run a script in the Github repository that makes the translation files compatible.

nod_’s picture

Version: 9.4.x-dev » 10.0.x-dev
Category: Feature request » Task
Issue tags: +JavaScript

can't be a feature request if it's a stable blocker no?

wim leers’s picture

#12++

nod_’s picture

Status: Active » Needs review

All right so what changed:

  1. Structure of the vendor/ckeditor5 files.
    Before
    ckeditor5/
      - translations/*
      - basic-styles.js
      - source-editing.js
      - ...
    

    After

    ckeditor5/
      - basic-styles/
        - translations/*
        - basic-styles.js
      - source-editing/
        - translations/*
        - source-editing.js
      - ...
    

    The vendor-update command is updated to do this now.

  2. To say that your plugin/module has ckeditor translations a dependency on core/ckeditor5.translations library needs to be added. It is done for the core libraries where relevant. If you declare the dependency and no translation files exists you will end up with a 404 script when the page loads.
  3. There is some magic going on to enable translation files to be aggregated together.
nod_’s picture

One issue is that on load the language is not applied (for basic_html) but when I change to full_html the language is applied properly, and going back to basic_html it's back to english. Will need to find what happens there.

One thing not done is mapping drupal langcode to ckeditor langcode. That might cause a few issues, there is a todo in there.

nod_’s picture

Issue is in the settings merging. When the language plugin is enabled it overwrites the language setting and the editor is not switched to the appropriate language.

lauriii’s picture

nod_’s picture

Issue summary: View changes
nod_’s picture

wim leers’s picture

Status: Needs review » Needs work

#15 makes a ton of sense — thanks so much for that explanation! 😊

Also see #3250191-24: Translation of toolbar button tooltips not working when text part language plugin is enabled — that is IMHO a hair removed from RTBC.

Wow GitLab fails spectacularly when looking at this merge request… :O I spent more time trying to scroll to the relevant piece and trying to post a comment at all than actually reviewing…

Review posted on the MR.

nod_’s picture

Status: Needs work » Needs review
wim leers’s picture

Title: API for contrib projects to load CKEditor translations » [PP-1] API for contrib projects to load CKEditor translations
Related issues: +#3262160: Simplify code in assets.js, remove mix of await and promise code

I just found out this is implicitly blocked on #3262160: Simplify code in assets.js, remove mix of await and promise code — making that explicit now.

nod_’s picture

Title: [PP-1] API for contrib projects to load CKEditor translations » API for contrib projects to load CKEditor translations
wim leers’s picture

I think this is RTBC once we also have green patches for 9.3.x and 9.4.x 🚀🥳 And thanks to the existing test coverage plus the bug that was fixed a few days ago with test coverage (#3250191: Translation of toolbar button tooltips not working when text part language plugin is enabled), we can be very confident that this approach is actually working. 👍

The changed strategy in CKE5 asset loading makes sense. It is conceptually super simple, simpler than before, which is a good quality 😄 But on the flip side, there's more individual assets to load, which makes me want to mark #3224261: [PP-1] Front-end performance: concatenate CKEditor 5 JS assets for every unique configuration a Major stable blocker. That's an absolutely fine trade-off IMHO.

P.S.: reviewing this on GitLab is now officially impossible. Had to clone it locally and generate diffs for specific files. 🙃 (f.e. git d 302b310392849b95c9aee41542f272de79722a5e HEAD -- core/scripts/js/assets.js)

nod_’s picture

But on the flip side, there's more individual assets to load

not quite :)

When aggregation is enabled it's the same as before: 1 file containing all the translations, separate from the other aggregates. So no overhead when aggregation is ON.

wim leers’s picture

#26: yes, I realize that — I did mean in the scenario when aggregation is not on :)

Can we get 9.3 & 9.4 patches? :)

nod_’s picture

StatusFileSize
new1.64 MB

9.4 patch, waiting on the other backport for 9.3

wim leers’s picture

Status: Needs review » Reviewed & tested by the community

#3262160: Simplify code in assets.js, remove mix of await and promise code was backported to 9.3! I think that means #28 can be tested against 9.3 as well?

In any case, this means that this issue now is committable to 2 out of 3 branches already, so moving ahead to RTBC :)

Very nice work here! 👏

nod_’s picture

9.3 version this is still ckeditor 31.0.0 in this branch so a bit less translations available.

no idea why the file size is so different though

lauriii’s picture

Status: Reviewed & tested by the community » Needs work

Posted few comments on the MR but this looks really close to being ready for me 👍

nod_’s picture

Status: Needs work » Needs review

Added some documentation and fixed a few things to make the rendered page better (currently it's https://api.drupal.org/api/drupal/core%21modules%21ckeditor5%21ckeditor5...) the @see can't be multiline, added some headers to the code blocks to make it more explicit what/where things are happening.

wim leers’s picture

Status: Needs review » Reviewed & tested by the community
lauriii’s picture

Issue tags: +Needs change record

I think it would be good to write change record for the new API as well.

wim leers’s picture

Got confirmation from the CKEditor 5 team:

lauriii Today at 1:19 PM
@reinmar We are implementing a translation discovery for contributed Drupal modules. We are wondering if it’s a reasonable assumption for us to make that the languages supported by ckeditor5-dll  is always a superset compared to plugins. In other words, we are assuming that other plugins are not providing translations for languages that aren’t available in the ckeditor5-dll translations.

reinmar  2 hours ago
Oh dear… in 99.9% that should be true. But technically speaking, I think that it’s possible for a plugin to have more translations than the base. I may check this, if it’s a crucial info.

lauriii  1 hour ago
I guess that might be sufficient. We could always change how the translations are loaded if we discover that it was a false assumption

🚀

nod_’s picture

wim leers’s picture

Issue tags: -Needs change record

Change record looks great 😄

nod_’s picture

StatusFileSize
new1.64 MB

D9 version

nod_’s picture

StatusFileSize
new1.64 MB

fix bad reroll

  • lauriii committed 0208498 on 10.0.x
    Issue #3228464 by nod_, Wim Leers, lauriii, Reinmar: API for contrib...

  • lauriii committed 47a9a9a on 9.4.x
    Issue #3228464 by nod_, Wim Leers, lauriii, Reinmar: API for contrib...
lauriii’s picture

Version: 10.0.x-dev » 9.3.x-dev
Status: Reviewed & tested by the community » Patch (to be ported)

Committed to 10.0.x and 9.4.x. We probably want to backport this to 9.3.x so that contrib can start using this. We still need a separate patch for that.

nod_’s picture

Status: Patch (to be ported) » Needs review
StatusFileSize
new1.58 MB

9.3 version of the patch. It's still using ckeditor 31.0.0 and not the 31.1.0 we have in d10/d9.4

hooroomoo’s picture

Status: Needs review » Reviewed & tested by the community

reviewed 9.3 patch and tested locally that expected translation files load with es and af locale codes. LGTM :)

wim leers’s picture

#44: Woah!! I think it is a mistake/oversight that #3258250: Update to CKEditor5 v31.1.0 never was cherry-picked to 9.3?!

lauriii’s picture

Status: Reviewed & tested by the community » Fixed

Committed 33f8ef2 and pushed to 9.3.x. Thanks!

  • lauriii committed 33f8ef2 on 9.3.x
    Issue #3228464 by nod_, Wim Leers, lauriii, Reinmar: API for contrib...

Status: Fixed » Closed (fixed)

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