Перевод в JS-файлах
Локализация в PHP-файлах уже давно является стандартом для WordPress, но перевод в JS-файлах, который осуществлялся через функцию wp_localize_script(), оставлял желать лучшего. С выходом WordPress 5.0 появилась возможность использовать функции локализации, такие как __() и _x(), прямо в JS-файлах так же просто, как и в PHP.
Содержание:
- Как это работает
- Создание файла перевода JSON
- Вариант 1: Создание с помощью WP-CLI (рекомендуется)
- Вариант 2: Конвертация с помощью gulp
- Шаг 1. Создание .po файла
- Шаг 2. Конвертация .po файла в .json
- Вариант 3: Публикация плагина/темы в каталоге WordPress
- Название файла перевода JSON
- Хуки
Как это работает
Чтобы WordPress знал, что ваш скрипт имеет перевод и какой текстовый домен (ID) использовать для этого перевода, необходимо воспользоваться функцией wp_set_script_translations().
Пример кода:
wp_register_script( 'my-handle', plugins_url( '/js/my-file.js', __FILE__ ) );
wp_set_script_translations( 'my-handle', 'my-domain' );
Функция wp_set_script_translations() добавляет зависимость на основной скрипт для wp-i18n и включает .json файл с переводами.
Теперь в вашем JS-коде вы должны использовать объект wp.i18n следующим образом:
const { __, _x, _n, _nx } = wp.i18n;
__('Hello', 'myl10n');
_x('Hi', 'short word', 'myl10n');
_n('%s star', '%s stars', 5, 'myl10n');
_nx('%s star', '%s stars', 5, 'superstars', 'myl10n');
sprintf(__('See Link: %s', 'myl10n'), 'http://site.com');
Функции перевода, которые использованы, полностью аналогичны тем, что используются в PHP.
Теперь настройка для перевода JS-файлов завершена! Единственное, что осталось, это создать файлы перевода .json, из которых будут использоваться переведённые строки. Как это сделать, читайте ниже.
Заметки:
- Отсутствие функций, таких как
esc_html(), объясняется тем, что они не нужны в JavaScript, так как браузер сам справляется с экранированием небезопасных символов. - Содержимое JSON-файла перевода выводится напрямую в HTML-страницу в виде JavaScript-кода, перед скриптом, для которого включается перевод.
- Рекомендуется избегать использования HTML в переведённых строках, но иногда это необходимо, например, для добавления ссылок:
Проверьте <a href="%s">мой сайт</a>. На данный момент это сложно сделать без использованияinnerHTML(что может быть опасно). Эта ситуация обсуждается на GitHub. - Если зарегистрировано несколько скриптов, для которых необходимы переводы, то переводы нужно включать для каждого скрипта отдельно.
wp_register_script('my-plugin-script', plugins_url('js/my-script.js', __FILE__), ['wp-i18n'], '0.0.1');
wp_set_script_translations('my-plugin-script', 'my-plugin');
wp_register_script('my-awesome-block', plugins_url('js/my-block.js', __FILE__), ['wp-i18n'], '0.0.1');
wp_set_script_translations('my-awesome-block', 'my-plugin');
Этот подход нужен для оптимизации: в HTML добавляются только переведённые строки, используемые в включённом скрипте — ничего лишнего.
Создание файла перевода JSON
Вариант 1: Создание с помощью WP-CLI (рекомендуется)
Для этого метода вам нужен уже готовый файл PO, в котором, помимо переводов для PHP-файлов, есть также переводы для JS-файлов. Обычно, чтобы включить переводы из JS-файлов в основной файл PO, ничего дополнительно делать не нужно — всё происходит по умолчанию.
Предположим, что в вашем плагине есть папка languages и в ней несколько PO-файлов с переводами для разных языков, включая строки из JS-файлов.
Чтобы создать .json файлы из существующих .po файлов, вы можете использовать команду wp i18n make-json.
wp i18n make-json languages --no-purge
languages— путь относительно вашего плагина/темы к папке, где находятся .po файлы. .json файлы появятся в той же папке. Если вам нужно создать .json файлы в другом месте, укажите путь как второй параметр команды.--no-purge— флаг, который указывает не удалять строки перевода из PO файла. По умолчанию строки удаляются.
Как создается MD5-хэш
При создании .json файла он будет иметь следующий формат: {domain}-{locale}-{md5}.json, где md5 хэш создаётся из пути к файлу, взятого из PO файла.
Пример:
В PO файле строка перевода может выглядеть так:
#: scripts.js:9
msgid "Hello"
msgstr "Привет"
Тогда md5 будет создан из строки: md5('scripts.js').
Если PO файл содержит переводы для нескольких .js файлов, будут созданы несколько .json файлов для каждого из них.
Вариант 2: Конвертация с помощью gulp
Шаг 1. Создание .po файла
Создайте файл с нужными строками перевода. Например, создайте файл /languages/js/myl10n-ru_RU-my-script.po и добавьте в него следующий код:
msgid ""
msgstr ""
"Project-Id-Version: my-plugin-namen"
"POT-Creation-Date: 2020-04-28 12:17+0500n"
"PO-Revision-Date: n"
"Last-Translator: Kama <[email protected]>n"
"Language-Team: WP Kaman"
"Language: run"
"MIME-Version: 1.0n"
"Content-Type: text/plain; charset=UTF-8n"
"Content-Transfer-Encoding: 8bitn"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);n"
"X-Poedit-SourceCharset: UTF-8n"
"X-Poedit-KeywordsList: __;_e;_x:1,2c;_ex:1,2c;_n:1,2;_nx:1,2,4c;_n_noop:1,2;"
"_nx_noop:1,2,3c;esc_attr__;esc_attr_e;esc_html__;esc_html_en"
"X-Generator: Poedit 2.3n"
"X-Poedit-Basepath: ../..n"
"X-Poedit-SearchPath-0: scripts.jsn"
"X-Poedit-SearchPathExcluded-0: node_modulesn"
Обратите внимание на строки, указывающие путь к вашему JS-файлу.
Теперь откройте программу Poedit, перетащите в неё ваш PO файл, нажмите "Обновить из кода", переведите полученные строки и сохраните файл.
Шаг 2. Конвертация .po файла в .json
Для этого нам понадобятся библиотеки po2json и jed, потому что конверсия должна быть выполнена в формате jed. Установите их в проект с помощью следующих команд:
npm install -D po2json
npm install -D jed
Добавьте следующий код в файл gulpfile.js:
let po2json = require('po2json'),
Jed = require('jed'),
Write = require('write');
gulp.task('po2json', async ()=>{
// путь к PO файлу
let PO_file = 'languages/js/myl10n-ru_RU-my-script.po'
po2json.parseFile(PO_file, { format:'jed' }, (err, jsonData)=>{
let i18n = new Jed(jsonData)
let JSON_file = PO_file.replace('.po', '.json')
Write.sync(JSON_file, JSON.stringify(i18n, null, 2), { newline: true })
})
})
Теперь создайте json файл с помощью команды:
gulp po2json
Таким образом, рядом с .po файлом появится .json файл. Процесс создания .json файла можно настроить так, чтобы изменения в .po файле автоматически отражались в .json файле.
Вариант 3: Публикация плагина/темы в каталоге WordPress
При публикации плагина в каталоге WordPress все JS файлы автоматически анализируются так же, как и PHP файлы. Все найденные переводы будут добавлены на translate.wordpress.org, что позволит сообществу делать переводы.
Таким образом, файлы перевода .json создаются автоматически. Необ��одимо только указать параметры Text Domain: и Domain Path: в заголовках плагина, а затем перевести полученные строки на сайте GlotPress.
Название файла перевода JSON
Файл перевода JSON должен иметь определённое название, чтобы функция wp_set_script_translations() могла найти соответствующий файл при попытке его загрузки.
Существует два варианта: когда третий параметр $path указан и когда он не указан.
-
При отсутствии третьего параметра
$path:/wp-content/languages/themes/{domain}-{locale}-{md5}.json//plugin-ru_RU-db8f629adc6c4c33f29613cfb71a6038.json -
При наличии третьего параметра
$path:SPECIFIED_PATH/{domain}-{locale}-{handle}.json//plugin-ru_RU-script.jsonSPECIFIED_PATH/{domain}-{locale}-{md5}.json//plugin-ru_RU-db8f629adc6c4c33f29613cfb71a6038.json/wp-content/languages/themes/{domain}-{locale}-{md5}.json//plugin-ru_RU-db8f629adc6c4c33f29613cfb71a6038.json
MD5 хэш в названии формируется из пути к файлу относительно папки плагина/темы.
Хуки
WordPress предоставляет фильтры, такие как load_textdomain и gettext, которые позволяют переопределять путь к файлам перевода или отдельным переводам.
В WordPress 5.0.2 были добавлены следующие фильтры для настройки работы wp_set_script_translations() для переводов на JavaScript:
pre_load_script_translations— срабатывает в начале функции и позволяет полностью переопределить функциональность функцииload_script_translations().load_script_translation_file— позволяет изменить путь к файлу перевода для конкретного скрипта.load_script_translations— позволяет изменять полученный код JSON файла.
Теперь вы знаете, как правильно делать переводы в JS-файлах WordPress, создавая удобные и понятные для пользователей интерфейсы!