Cách sử dụng i18n làm multiple language javascript (ok)

https://github.com/dfwood/i18n-example

Ví dụ 1:

C:\xampp\htdocs\datvietcoconut\wp-content\themes\twentyseventeen\functions.php

function twentyseventeen_scripts_ct() {
    wp_enqueue_script ( 'my-plugin-script' , get_template_directory_uri() .'/js/my-script.js'  , array (  'wp-i18n'  ) , '0.0.1',true ) ;
    wp_set_script_translations ('my-plugin-script' ,  'my-plugin',get_template_directory() . '/languages') ;
}
add_action( 'wp_enqueue_scripts', 'twentyseventeen_scripts_ct' );

C:\xampp\htdocs\datvietcoconut\wp-content\themes\twentyseventeen\js\my-script.js

const { __, _x, _n, sprintf } = wp.i18n;
const outputContainer = document.getElementById('i18n-js-examples');
const strings = [
  __('Hello World', 'my-plugin'),
  __('Glitter Box', 'my-plugin')
];
outputContainer.innerHTML = strings.join('<br/>');

C:\xampp\htdocs\datvietcoconut\wp-content\themes\twentyseventeen\languages\my-plugin-vi-my-plugin-script.json

{ 
   "domain" :  "my-plugin" , 
   "locale_data" :  { 
      "my-plugin" :  { 
         "" :  { 
            "domain" :  "my-plugin" , 
            "plural_forms" :  "nplurals=2; plural=(n != 1);" , 
            "lang" :  "vi" 
         } , 
         "Hello World": ["Xin chào thế giới 😁"],
         "Glitter Box": ["Chiếc hộp kỳ diệu 😁"], 
      } 
   } 
}

C:\xampp\htdocs\datvietcoconut\wp-content\themes\twentyseventeen\header.php

<div id="i18n-js-examples"></div>

Chú ý với cách đặt ngôn ngữ khác ví dụ: en-AU

C:\xampp\htdocs\datvietcoconut\wp-content\themes\twentyseventeen\languages\my-plugin-en_AU-my-plugin-script.json

{ 
   "domain" :  "my-plugin" , 
   "locale_data" :  { 
      "my-plugin" :  { 
         "" :  { 
            "domain" :  "my-plugin" , 
            "plural_forms" :  "nplurals=2; plural=(n != 1);" , 
            "lang" :  "en-AU" 
         } , 
         "Hello World": ["Xin chào thế giới 😁"],
         "Glitter Box": ["Chiếc hộp kỳ diệu 😁"], 
      } 
   } 
}

Plugin gốc

Plugin chỉnh sửa tiếng việt để test

WordPress 5.0+ JavaScript localization translation

October 27, 2020 John Tutorial

Article directory [hide]

  • WordPress JavaScript internationalization

    • JavaScript localization functions

    • Load JavaScript translation

    • JavaScript translation file

      • JavaScript translation file name

      • Generate JavaScript translation files

  • Tools to increase efficiency

    • Webpack configuration

    • Babel integration

    • Available hooks and filters

  • WordPress PHP Internationalization

  • Further reading

Advocate mentioned that WordPress supports JavaScript localization translation in “WordPress 5.0+ supports JavaScript i18n localization translation”. Today, Advocate will share with you the article “The Internationalization of WordPress 5.0” from @Pascal Birchler. It comprehensively introduces the entire implementation of JavaScript localization translation. I hope it will be helpful to all developers.

WordPress JavaScript internationalization

WordPress 5.0 comes with a new editor called Gutenberg. This new editor is mainly written in JavaScript, which means that many international translations happen on the client instead of the server. Although the core of WordPress used to use wp_localize_script() functions to translate the fields of the UI interface, in the face of complex JavaScript plugins like Gutenberg, a more powerful solution is needed.

JavaScript localization functions

WordPress 5.0 adds support JavaScript I18N, which is bringing PHP as a function similar to what we are familiar with JavaScript developers, this is a new start wp-i18nof JavaScript package that provides new functions __(), , _x(), _n(), _nx()even sprintf(). These functions are basically the same as the original PHP functions and can be used in the same way.

To use this package, you need wp-i18nto add the script as a dependency when registering JavaScript:

wp_register_script ( 
	'my-plugin-script' , 
	plugins_url (  'js/my-script.js' ,  __FILE__  ) , 
	array (  'wp-i18n'  ) , 
	'0.0.1' 
) ;

Then, the localized functions wp.i18nare available under global variables in JavaScript. You can use them like this:

const  { __ , _x , _n ,  sprintf  }  = wp . i18n ;
__ (  'Hello World' ,  'my-plugin'  ) ;
_x (  'Glitter Box' ,  'block name' ,  'my-plugin'  ) ;
// Get the number of comments anywhere in your js script. 
const commentCount = wp . Data . Select (  'my/data-store'  ) . GetCommentCount ( ) ;
/* translators: %s: number of comments */ 
sprintf ( _n (  'There is %s comment' ,  'There are %s comments' , commentCount ,  'my-plugin'  ) , commentCount ) ;

This is all you need to make JavaScript components fully localizable.

If you are familiar with the PHP translation function in the core of WordPress, you will find that similar esc_html()or missing esc_html__(). These are not needed in JavaScript, because browsers can already escape unsafe characters.

Note : Although the use of HTML in translatable strings is discouraged, sometimes it is necessary, such as adding a link ( Check out this link to <a href="%s">my website</a>.). Now, it’s not easy to do this, at least without using innerHTML / dangerouslySetInnerHTML. Currently, this issue is being discussed on GitHub.

wp_register_script ( 
	'my-plugin-script' , 
	plugins_url (  'js/my-script.js' ,  __FILE__  ) , 
	array (  'wp-i18n'  ) , 
	'0.0.1' 
) ;
wp_register_script ( 
	'my-awesome-block' , 
	plugins_url (  'js/my-block.js' ,  __FILE__  ) , 
	array (  'wp-i18n'  ) , 
	'0.0.1' 
) ;
wp_set_script_translations (  'my-plugin-script' ,  'my-plugin'  ) ; 
wp_set_script_translations (  'my-awesome-block' ,  'my-plugin'  ) ;

The reason for this is for performance . The translation will only be loaded when your script is actually queued . If this is the case, WordPress will load the translation file into memory and provide it via inline JavaScript wp.i18n. This means that WordPress needs a translation file for each script handle , and each file only contains strings related to the script.

Imagine writing a WordPress plugin that includes JavaScript, which contains many different packages, which can also be used independently of each other. If you only need those translations for a single package, you don’t want to load all the translations.

JavaScript translation file

We have already introduced how to load JavaScript translation files, but what is so special about them? Well, this time we will not deal with PO or MO files, but use JSON files. Since JSON can be easily read in JavaScript, it is a convenient format to store translations.

In addition, the wp-i18n package uses a library that is basically compatible with the Jed JavaScript gettext library, which requires Jed-style JSON conversion data. As mentioned in the previous section, WordPress.org will automatically provide these translation files. But if you want to load your own translation, you need to create such a JSON file yourself.

A very simple Jed style JSON translation file looks like this:

{ 
   "domain" :  "messages" , 
   "locale_data" :  { 
      "messages" :  { 
         "" :  { 
            "domain" :  "messages" , 
            "plural_forms" :  "nplurals=2; plural=(n != 1);" , 
            "lang" :  "de_DE" 
         } , 
         "Source" :  [ 
            "Quelle" 
         ] , 
         "Enter the information for this recommendation." :  [ 
            "Gib die Informationen zu dieser Empfehlung ein." 
         ] , 
         "%s comment" :  [ 
            "%s Kommentar" , 
            "%s Kommentare" 
         ] , 
         "block name \u 0004Recommendation" :  [ 
            "Empfehlung" 
         ] 
      } 
   } 
}

If you are already familiar with PO translation files, this format contains similar information, such as information about locale ( de_DE) and its plural forms. All strings are in the messagesobject, the original is the key, and the translation is the value. If a string has an additional context, it will be separated by the \u0004 separator.

Note: An important detail here is the text field, which is currently only available messages , not the field you actually use in your code. Here is a WordPress Trac ticket, which may support the use of actual text fields in the future.

JavaScript translation file name

PO and MO translation files in WordPress usually have formats $textdomain-$locale.po, for example my-plugin-de_DE.po. But for JSON files, the situation is a bit different.

You may remember that we need to pass the script handle name to wp_set_script_translations(). This handle also needs to add the json file name $textdomain-$locale-$handle.json.

Therefore, for our my-plugin-script script handle, the translation file needs to be named my-plugin-de_DE-my-plugin-script.json.

For technical reasons, WordPress also looks for files in the form $textdomain-$locale-$md5.json, which $md5 contains the MD5 hash of the JavaScript file name, including the extension. In the previous example, my-plugin-script point to js/my-script.js. my-script.js The MD5 hash value is 537607a1a008da40abcd98432295d39e. So our translation file can also be named my-plugin-de_DE-537607a1a008da40abcd98432295d39e.json.

Generate JavaScript translation files

Since WordPress requires a translation file for each script handle, each file only contains strings related to the script, which means processing a large number of JSON files. Fortunately, there is no need to write these by hand .

The recommended way to generate JSON translation files is to use WP-CLI. The latest version of WP-CLI 2.1.0 provides special commands for this purpose wp i18n make-json .

This wp i18n make-jsoncommand can extract all JavaScript strings from regular PO translation files and put them into a separate JSON file.

Note: WP-CLI 2.1.0 was released on December 18. Make sure you are wp cli updateusing the latest version by running . You can use to wp cli versioncheck the current version.

Let’s assume your plugin folder in the file my-plugin have three source files: my-plugin.php, js/my-script.js and js/my-block.js. You use WP-CLI to extract the string and generate a translation catalog (POT) as shown below:

wp i18n make -pot my-plugin my-plugin/languages/my-plugin. pot

Use the poedit software to translate the generated .pot files and generate the required PO and MO files. Suppose we first add a German translation my-plugin/languages/my-plugin-de_DE.po. After that, you only need to run it wp i18n make-json my-plugin/languages to generate JavaScript translation files. The results are as follows:

  • A new my-plugin/languages/my-plugin-de_DE-537607a1a008da40abcd98432295d39e.jsonfile contains translations my-script.js.

  • A new my-plugin/languages/my-plugin-de_DE-dad939d0db25804f91959baeec56ea8a.json file contains translations my-block.js.

  • In my-plugin/languages/my-plugin-de_DE.ponow contains only the need to be translated on the server side.

If you don’t want to modify the PO file, please --no-purge pass parameters to the WP-CLI command as described in the documentation.

Note: These WP-CLI commands have some known problems in some special situations. When we understand how people use them, we are always working to improve the tools.

ools to increase efficiency

These new processes introduced by WordPress 5.0 and Gutenberg can feel a bit complicated at first. To make life easier, I want to share some tips and tricks for project configuration.

ebpack configuration

If you need to reference global variables in the project anywhere wp.i18n, you will not be satisfied with the code editor displaying type hints and the like. To change this situation, I recommend installing @wordpress/i18n packages as dependencies of using npm / yarn. Then you can use it throughout the project import { __ } from '@wordpress/i18n; .

Usually, this will cause Webpack to bundle the library with your code. Since WordPress has already wp.i18n exposed the library globally, there is no need for code duplication. To prevent this, add the following to the Webpack configuration:

externals :  { 
    '@wordpress/i18n' :  {  this :  [  'wp' ,  'i18n'  ]  } 
}

In this way you can benefit from the functions of the IDE and the existing wp.i18nglobal functions. Just make sure wp_register_script()to add it wp-i18nas a dependency when calling .

Babel integration

In the previous section, I mentioned using wp i18n make-pota pot to create the necessary translation directory, from which you can create the actual localization. Depending on your developer workflow, you may want to call the build tool using Babel @wordpress/babel-plugin-makepotto create the POT file. Next, share the integration with Babel to extract the I18N method.

npm install --save-dev @wordpress/babel-plugin-makepot Next , please run the directory and add the following code to your Babel configuration:

[ 
    '@wordpress/babel-plugin-makepot' , 
    { 
        output :  'languages/my-plugin-js.pot' , 
    } , 
]

Advocating tips: If you are not familiar with how to integrate Babel and configure Webpack, I suggest you read this article: https://www.bluehost.com/blog/developers-corner/javascript-translations-in-gutenberg-9931 /

Note: You still want to create POT files for other PHP files, not just JavaScript files. You can still use WP-CLI to do this. Just skip the JavaScript string extraction and merge the generated POT file as shown below:

wp i18n make - pot my - plugin my - plugin / languages / my - plugin. pot  - skip - js - merge = my - plugin / languages / my - plugin - js. pot

In this case, it languages/my-plugin-js.potis only temporary, so you can delete it again later.

Available hooks and filters

WordPress provides load_textdomain and gettext such filters allow rewriting the translation file path or personal translation.

In WordPress 5.0.2, the following filters are added for changing wp_set_script_translations() the results, so you can do the same for JavaScript translation:

  • pre_load_script_translations: Pre-filter the script conversion of a given file, script handle and text field. In this way, you can short-circuit the script conversion logic to return your own translation.

  • load_script_translation_file: Filter the file path used to load the script conversion of the given script handle and text field.

  • load_script_translations: Filter script conversion for a given file, script handle and text field. This way, you can overwrite the translation after loading the translation from the translation file.

In addition, pull request # 12517 Gutenberg project also @wordpress/i18n pack increase in the i18n.gettext, , i18n.gettext_with_context, i18n.ngettextand i18n.ngettext_with_contextfilters. To overwrite individual translations, you can use them like this:

wp. hooks . addFilter ( 
    'i18n.gettext' , 
    'myplugin/filter-gettext' , 
    function ( translation , text , domain )  { 
        if  (  'Source'  === text &&  'foo-domain'  === domain )  { 
            return'New  translation' ; 
        }
 
        return translation ; 
    } 
) ;

WordPress PHP Internationalization

In this article, we mentioned a lot of JavaScript translations, and you might be wondering if we also changed things in PHP. The answer is: no.

However, now is a good time to do some kind of I18N cleaning for your plugin or theme. Here is some useful information:

  • Make sure to set it in the main plugin file/theme style sheet Text Domain, and use the same text field throughout the project.

  • If your WordPress plugin or theme is hosted on WordPress.org and requires WordPress 4.6 or higher ( Tested up toindicated by the title in the readme file), you don’t need to call it load_plugin_textdomain().

  • You can run wp i18n make-pot --debugto see which translatable strings should be improved.

Further reading

  • Dev Note on the new JavaScript internationalization support

  • Internationalization best practices in the plugin developer manual

  • Internationalization in the Gutenberg Manual

Original: Internationalization in WordPress 5.0, published on December 20, 2018, translated by Advocate@WordPress大学. Reprinting and misappropriation of the translation is prohibited without permission!

Advocate summary: The translation field in javascript needs to be extracted and generated by the methods mentioned in the article to generate the pot file, and then use the poedit software to import the pot to translate the .po file, and then use the WP-CLI command or po2json to convert the content of the po to generate a json file ,This is done.

Last updated