3

The internationalisation of my theme is defined in functions.php and the javascript file to be internationalised uses the wp-i18n library. The translation function __('string',text-domain'); is recognised correctly and the default language (fr) is displayed correctly. But the translation is never found by the wp_set_script_translations() function when en_GB language is localeData.

The internationalization works perfectly with php for my custom theme and plugins !Also my custom translation plugin works perfectly with en_GB.

What files is used to read translation : textdomain-loc_ale-md5.json file or textdomain-loc_ale.po and textdomain-loc_ale.mo files ?

wp_set_script_translations(): Is it possible to call wp_set_script_translations() inside functions.php (theme folder)? If yes, does I make a mistake In my code ? Does "init" is the good action hook to use to load wp_set_script_translations() from the theme folder ? I tried to add and move slash to the directory of file.js and languages folder but it's still not working.

json file : Should the -{md5} part of the json file name be kept or can something else be used, from theme folder?

json parameters : What do the elements "domain": "messages" and "locale_data":{"messages":{"":{"domain": "messages","lang":"en_GB",.. in the json file script correspond to or refer to? Should "messages" be replaced by "text-domain"? If yes , how to filled this element directly from Cli-Command and why it's not filled automatically ?

The official documentation of i18n doesn't talk about that.

Theme/script/file.js :

var localeData = $('html').prop('lang');
localeData = localeData.replace('-', '_'); //return en_GB
const { __ } = wp.i18n;
const textdomain = 'text-domain';
__( '__', 'ActivUs' );
wp.i18n.setLocaleData(localeData,'text-domain');

Theme/functions.php :

add_filter('locale', 'getnewlocale');
function getnewlocale($locale) {
  $gen_locale = explode('/',$_SERVER["REQUEST_URI"])[1];
  if ( !is_admin() ) {
    $locale = ($gen_locale == 'fr') 
      ? 'fr_FR' 
      : (($gen_locale == 'en') ? 'en_GB' : '' );
    return $locale;
  }
}

add_action("after_setup_theme", function () {
  load_theme_textdomain(
    'text-domain',
    get_stylesheet_directory() . '/languages'
  );
}, 5);

add_action( 'init', 'js_load_text_domain' );
function js_load_text_domain() {
  wp_set_script_translations(
    get_stylesheet_directory() . '/script/file.js',
    'text-domain',
    get_stylesheet_directory() . '/languages/'
  );
}
// get_stylesheet_directory() . '/languages'

Files in the "Theme/languages" folder :

text-domain-en_GB-md5.json
en_GB.mo
en_GB.po
text-domain.pot

Example of Theme/languages/en_GB.po file:

#: script/file.js:969
#: script/file.js:2094
msgid "Revenir à la page précédente"
msgstr "Go back to previous page"

-------------UPDATE-------------

All my javascript files from theme folder were called inside header.php and footer.php. To get $handle for my file.js inside theme folder I had to decide to enqueue this one like that :

function actionjs_enqueue_scripts() {
  wp_enqueue_script(
    'main-action',
    get_template_directory_uri() . '/script/file.js',
    array('jquery', 'wp-i18n' ),
    '1.0.0', true
  );
}
add_action( 'wp_enqueue_scripts', 'actionjs_enqueue_scripts' );

My $handle ("id" of file.js) is 'main-action'.

According to the documentation it seems necessary to call the Hook of wp_set_script_translations() after enqueued script like that (priority = 100):

function load_js_text_domain(){
  wp_set_script_translations(
    'main-action',
    'text-domain',
    get_stylesheet_directory().'/languages'
  );
}
add_action( 'wp_enqueue_scripts', 'load_js_text_domain', 100 );

At the moment I'm not sure of anything as the translation is still not loading.

How can I check that the .json or .po file is being read? Check that the name of the json file is correct? I've tried so many combinations.

I still don't know which file is read for translation. Is it text-domain-en_GB-my-handle.json or en_GB.po?

1-If it's the .json file, do I have to add the translation by hand from the .po file that's already been translated?

2-Why doesn't the make-json command do this automatically (cli-command)? However, I see that the source of .json file is the /script/file.js.

3-Does wp_set_script_translations automatically decode the json or do I have to use json_decode()? This is how a value in the json file looks like :

"Revenir \u00e0 la page pr\u00e9c\u00e9dente":[""]

Must I filled that [""]? If I add ["Go to the previous page"], nothing happens !

1 Answer 1

0

Good News after 2 days!

I resolved my issue, but I believe that wp i18n make-json does not generate the json file correctly. Why?

Because it uses the ISO codes and not the locale (get_locale()) from the browser/user. So it isn't "en_GB" that should be used but "en" in the .json file.

This :

"locale_data": {"messages": { "lang": "en_GB",...

should be :

"locale_data": {"messages": { "lang": "en",....

That means that you can't distinguish between 'en_US' and 'en_GB'. So it makes no sense to name these files (.po and .json) with the locale (en_GB) if json use only ISO 639 to retrieve used language.

As a reminder : Language_Country (en_GB) correspond to Language[ISO 639]_country[ISO 3166].

I also think it's a pity, even if the documentation specifies it, that wp i18n make-json (Cli Command) should automatically generate the name of the json file based on the files (at least for Wordpress) that already exist and assuming you already have a .pot and .po file.

For example, from these files: Awesome.pot , fr_FR.po, en_GB.pot with "Awesome" as the text-domain, obtain: Awesome-en_GB-md5.json and Awesome-fr_FR-md5.json.

Here the script to use to javascript internationalization for a script from the theme folder:

Theme/script/file.js doesn't change. see in the original question.

Files inside Theme/languages folder doesn't change.

Theme/functions.php :


function actionjs_enqueue_scripts() {
  wp_enqueue_script(
    'main-action',
    get_template_directory_uri() . '/script/action.js',
    array('jquery', 'wp-i18n' ),
    '1.0.0',
    true
  );
}

add_action( 'wp_enqueue_scripts', 'actionjs_enqueue_scripts' );

function load_js_text_domain(){
  wp_set_script_translations(
    'main-action',
    'your-text-domain',
    get_stylesheet_directory() . '/languages'
  );
}
add_action( 'wp_enqueue_scripts', 'load_js_text_domain', 100 );

add_action("after_setup_theme", function () {
  load_theme_textdomain(
    'your-text-domain',
    get_stylesheet_directory() . '/languages'
  );
});

The script for text-domain-en_GB-md5.json file looks like this :

{
    "translation-revision-date": "2023-09-14 19:28+0200",
    "generator": "WP-CLI\/2.8.1+infong1.1.2",
    "source": "script\/action.js",
    "domain": "your-text-domain",
    "locale_data": {
        "messages": {
            "": {
                "domain": "your-text-domain",
                "lang": "en", // And not "en_GB", only ISO 639
                "plural-forms": "nplurals=2; plural=(n != 1);"
            },
            "Ville principale": [
                "Main town"
            ],

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.