woocommerce / woocommerce-blocks

(Deprecated) This plugin has been merged into woocommerce/woocommerce
https://wordpress.org/plugins/woo-gutenberg-products-block/
GNU General Public License v3.0
403 stars 219 forks source link

Lazy-loaded translations cannot be customized #5305

Closed jacoswan closed 2 years ago

jacoswan commented 2 years ago

Describe the bug

It's not possible to translate WooCommerce Payments' "Save payment information to my account for future purchases." text using something like Loco Translate, or via a hook:

Screenshot 2021-12-03 at 19 38 58

To reproduce

Steps to reproduce the behavior:

  1. Active WooCommerce Payments and enable saving of payment details
  2. Add the Checkout Block to a page
  3. Try to translate the string in question with Loco Translate

Tried translating the string in both WooCommerce Payments (see below) and WooCommerce Blocks, neither works.

Possibly related to GlobalStep Some contents on the Payment pages and Checkout page fails to translate to the respective language.

Expected behavior

Should be able to translate the string. However, translating it with Loco Translate doesn't work on the normal checkout page with WooCommerce Payments either, but it's possible to work around it by using a filter.

Screenshots

See above.

Environment

WordPress (please complete the following information):

Desktop (please complete the following information):

Additional context

As seen in 4566468-zen

sunyatasattva commented 2 years ago

So, here is a summary of what was discovered in extensive troubleshooting:

The way common translation plugins usually work is by generating a .pot file (if not present) by gathering all the correctly marked strings to allow for easy localization by translators. Once a translation is done, .po and (possibly) .mo files are generated, which are then used by PHP plugins in the required contexts.

However, the way we do things is a bit different: most of the content of our plugin is dynamically loaded through JavaScript. Our translations don't use the standard WordPress .po files, but, instead, they use .json files. Furthermore, these JSON files are chunked into smaller bits so that they can be lazy loaded whenever required.

Generally, we use GlotPress to generate the community translations and, AFAIU, these then get automatically chunked correctly for our code to parse.

This means that, unless third-party plugins are capable of generating these chunks, translations provided by them will not be correctly loaded into our plug-in and there is no easy user-friendly way to provide custom translations. The best workaround is currently to provide an official translation. In the case of this issue shown in the OP, for example, the string has not yet been translated in our official files for French; so, the users could provide a translation there.

However, this is not ideal because:

  1. Users will need to wait for the official translations workflows (think about users of more rarely spoken languages)
  2. Users can't provide custom translations if they wish so

@jacoswan I'm changing the title of this issue if you don't mind, to make it more generic, as this seems to affect a much larger surface area than it previously looked like. However there is no guarantee on when we could tackle this issue as of now, so perhaps you might want to get back to your user with this info?


Link to the lazy loading logic: https://github.com/woocommerce/woocommerce-gutenberg-products-block/blob/e15a441e093989d70fd5f209e8726f791d40fab5/src/BlockTypes/Checkout.php#L369-L391

Aljullu commented 2 years ago

This means that, unless third-party plugins are capable of generating these chunks, translations provided by them will not be correctly loaded into our plug-in and there is no easy user-friendly way to provide custom translations.

Right, the way some WC Blocks strings are loaded differs from the rest of the strings in WP, so translation plugins need to update to support that. What's strange is that Loco Translate reports to support JSON translation files, so I would expect it to work.

@senadir what are your thoughts on this one? Should we add it to the backlog and do some more research?

senadir commented 2 years ago

It is to my understanding that we're not doing anything new around translations, WordPress would enqueue and then its json translation and we would lazy load a script and its lazy loaded translation.

A more practical example would be to test LocoTranslate with a script that is loaded via WP (so core blocks like Cart, Checkout, and even payment methods).

If all fails, you can still filter JS translation on frontend https://github.com/WordPress/gutenberg/blob/trunk/docs/reference-guides/filters/i18n-filters.md

sunyatasattva commented 2 years ago

From LocoTranslate docs:

WordPress gives priority to authors' own JSON files if they are named according the script handle, e.g. myDomain-fr_FR-myScript.json and will not look any further if it finds one. Loco Translate cannot generate JSON files with this naming convention. Authors can choose any unique handle they like and there is no way to derive this from a POT file.

Bear with my ignorance here, but could it be that since, e.g., the French translation is half there, Loco will not look further for the rest of the strings provided by the user?

If all fails, you can still filter JS translation on frontend

Indeed, but not very user friendly, especially on a large scale. Maybe one or two strings are alright, but, say you want to translate the entire thing in Armenian or whatnot, it would become unwieldy.

nerrad commented 2 years ago

Ultimately, the issue stems from third-party translation plugins needing to support newer JS-based translation options for WordPress (or lazy loaded translations which is something WordPress core doesn't currently support out of the box). We have mechanisms that work out of the box for translation files either created manually (from po files created by something like wp i18n make-json) or GlotPress. But on the fly translations by plugins like Loco-Translate won't support our lazy-loaded strings because the third party plugin would have to explicitly support it.

So that means, for folks using Loco-Translate to either translate missing language strings or wanting to add custom strings, their options are to contribute to the WordPress.org GlotPress strings for the plugin, or use JS i18n filters as Nadir suggested.

Since there's nothing more we can do for now, I'm going to close this. Discussion can continue though if folks have ideas on improving further.