ФункціїПлагінЦіниРесурси
Змінити мову
РесурсиWordPress JSON Translation: Переклад JavaScript редактора блоків

WordPress JSON Translation: Переклад JavaScript редактора блоків

SimplePoTranslate Team27 травня 2026 р.
WordPress JSON Translation: Переклад JavaScript редактора блоків

Ви переклали свій плагін. Рядки PHP ідеально відображаються в налаштуваннях адміністратора, у фронтенд-шаблонах, сповіщеннях електронною поштою — все локалізовано. Потім ви відкриваєте редактор блоків, і кожен напис у вашому власному блоці Gutenberg залишається вперто, глузливо англійською. Кнопка "Add Item", заголовки панелі інспектора, текст-заповнювач. Ваш файл .mo завантажено. То чому ж ці рядки не перекладаються?

Тому що з WordPress 5.0 і появою Gutenberg, рядки JavaScript взагалі не надходять з вашого файлу .mo. Їм потрібен абсолютно окремий, для кожного скрипта, файл JSON-перекладу WordPress — і якщо ви його не згенеруєте, ваш редактор блоків залишиться англійською, незалежно від того, наскільки повним є ваш файл .po. Це один з найпоширеніших і найзаплутаніших прогалин у локалізації в сучасній розробці WordPress. Цей посібник докладно пояснює, чому це відбувається, як працює система перекладу JSON, імена файлів з MD5-хешем, які збивають з пантелику всіх, і повний набір інструментів для виправлення цієї проблеми.

Чому рядки вашого редактора блоків залишаються англійською

Коротка відповідь: PHP і JavaScript використовують дві абсолютно різні системи доставки перекладів у WordPress, і ваш файл .mo надає переклади лише для PHP.

Дві системи перекладу, один плагін

Коли WordPress виконує load_plugin_textdomain(), він зчитує ваш скомпільований файл .mo в пам'ять PHP. Кожен виклик __(), _e() та _x() у вашому коді PHP шукає свій переклад там. Це працює, оскільки PHP рендерить на стороні сервера — дані .mo знаходяться в тому ж процесі.

JavaScript відрізняється. Код вашого блоку виконується в браузері, задовго після завершення роботи PHP. Він не може отримати доступ до файлу .mo на стороні сервера. Замість цього, пакет @wordpress/i18n — JS-еквівалент Gettext, що надає __(), _x() та sprintf() вашим скриптам — очікує, що переклади будуть доставлені як JSON-навантаження, прив'язане до конкретного скрипта, який їх потребує.

Що відбувається з неперекладеним JS-рядком

Отже, блок з такими рядками:

import { __ } from '@wordpress/i18n';

registerBlockType( 'myplugin/feature-box', {
    title: __( 'Feature Box', 'myplugin' ),
    edit: () => {
        return <Button>{ __( 'Add Item', 'myplugin' ) }</Button>;
    },
} );

ніколи не знайде "Feature Box" або "Add Item" у вашому файлі .mo, оскільки браузер ніколи не читає файли .mo. Ці рядки повинні надходити у форматі JSON, прив'язані до цього точного ідентифікатора скрипта. Якщо ви це не налаштували, виклики __() JavaScript просто повернуть оригінальний англійський текст — тихо, без помилок у консолі.

Підключення JSON-перекладів за допомогою wp_set_script_translations()

Мостом між вашим скриптом та його JSON-перекладами є єдина функція PHP: wp_set_script_translations(). Відповідь на запитання "як WordPress дізнається, який файл JSON належить до якого скрипта" така: ви повідомляєте йому про це, реєструючи скрипт, а потім оголошуючи його текстовий домен та папку, де зберігається JSON.

Реєстрація скрипта та його папки перекладів

add_action( 'init', function () {
    wp_register_script(
        'myplugin-editor',
        plugins_url( 'build/index.js', __FILE__ ),
        array( 'wp-blocks', 'wp-i18n', 'wp-element' ),
        '1.0.0'
    );

    // Tell WordPress where this script's JSON translations live
    wp_set_script_translations(
        'myplugin-editor',        // the registered script handle
        'myplugin',               // text domain
        plugin_dir_path( __FILE__ ) . 'languages'
    );
} );

Коли редактор завантажує myplugin-editor, WordPress тепер знає, що потрібно шукати в папці languages/ файл JSON, який відповідає цьому скрипту та локалі поточного користувача. Якщо він його знаходить, він вбудовує переклади перед виконанням вашого скрипта, і виклики __() JS розв'язуються коректно. Ідентифікатор, який ви передаєте, повинен точно відповідати зареєстрованому скрипту — невідповідний або відсутній ідентифікатор є другою найпоширенішою причиною тихої невдачі перекладів.

Ім'я файлу з MD5-хешем, якого ніхто не очікує

Ось деталь, яка збиває з пантелику майже всіх. Файл JSON, який шукає WordPress, не називається чимось акуратним, наприклад myplugin-fr_FR.json. Він називається з MD5-хешем вихідного шляху скрипта:

Розшифровка шаблону імені файлу

myplugin-fr_FR-a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6.json

Шаблон такий: {textdomain}-{locale}-{md5}.json, де хеш — це MD5 відносного шляху до файлу скрипта (наприклад, build/index.js), як він зареєстрований. WordPress обчислює цей хеш під час виконання, щоб знайти правильний JSON для правильного скрипта. Якщо ви назвете файл вручну, WordPress його не знайде, і ви будете клястися, що система зламана, тоді як вона просто шукає інше ім'я файлу.

Вам не потрібно обчислювати хеш самостійно. Команда WP-CLI i18n робить це за вас, саме тому ви повинні використовувати інструменти, а не створювати ці файли вручну. Однак розуміння того, що хеш існує, економить вам години, коли файл JSON присутній у languages/, але все одно ігнорується — це майже завжди невідповідність хешу імені файлу через зміну шляху скрипта.

Повний робочий процес: від make-pot до make-json

Хороша новина полягає в тому, що ви зберігаєте свої переклади в тих самих файлах .po, які вже використовуєте. JSON — це похідний артефакт, що генерується в кінці. Відповідь на запитання "чи потрібно мені окремо підтримувати JS-рядки" — ні — вони знаходяться в тих самих файлах .pot/.po, що й ваші PHP-рядки, а одна додаткова команда розділяє JS-рядки в JSON.

Конвеєр з чотирьох команд

Ось повний конвеєр:

# 1. Extract ALL translatable strings (PHP and JS) into one template
wp i18n make-pot . languages/myplugin.pot

# 2. Translate languages/myplugin-fr_FR.po as usual (Poedit, AI, etc.)

# 3. Compile the .mo for PHP strings (server-side, as always)
wp i18n make-mo languages/

# 4. Generate the MD5-hashed JSON files for JS strings
wp i18n make-json languages/ --no-purge

Команда make-pot з кроку 1 достатньо розумна, щоб сканувати як ваші файли .php, так і вихідний код .js/.jsx, тому один файл .po для кожної локалі містить все. Команда make-json з кроку 4 читає кожен перекладений файл .po, знаходить записи, що походять з файлів JavaScript, і записує один правильно хешований JSON для кожного скрипта. Прапорець --no-purge також зберігає JS-рядки у вашому файлі .po, щоб пізніше make-mo їх не втратив — без нього make-json видаляє JS-записи з .po, що дивує людей, які виконують команди в неправильному порядку.

Згенерований файл JSON виглядає як набір перекладів у форматі Jed:

{
  "translation-revision-date": "2026-06-12 10:00+0000",
  "generator": "WP-CLI/2.x",
  "domain": "messages",
  "locale_data": {
    "messages": {
      "": { "domain": "messages", "lang": "fr_FR" },
      "Feature Box": [ "Bloc fonctionnalité" ],
      "Add Item": [ "Ajouter un élément" ]
    }
  }
}

WordPress читає locale_data і передає його @wordpress/i18n до того, як ваш скрипт почне виконуватися. Тепер __( 'Add Item', 'myplugin' ) у браузері повертає Ajouter un élément, і ваш редактор блоків нарешті локалізовано.

Чим це відрізняється від i18next JSON

Обидві системи використовують JSON, обидві орієнтовані на JavaScript, і ця зовнішня схожість викликає справжню плутанину. Вони не є взаємозамінними. JSON-файл редактора блоків WordPress — це похідне від Gettext, з MD5-хешем, навантаження для кожного скрипта, що використовується @wordpress/i18n. i18next JSON — це плоский або вкладений файл ключ-значення, що використовується react-i18next або next-intl, зі своїм власним синтаксисом {{interpolation}} та конвенціями для множинних ключів.

Якщо ви працюєте з чистим React або Next.js за межами WordPress, вам потрібен підхід i18next, який ми розглянули у статті переклад i18next JSON в React та Next.js. Всередині WordPress вам потрібен робочий процес make-json, описаний вище. Їхнє змішування — наприклад, написання вручну плоского JSON-файлу в стилі i18next і очікування, що wp_set_script_translations() його завантажить — просто не спрацює, оскільки WordPress шукає хешований формат Jed, а не довільні пари ключ-значення.

Одне джерело, кожен потрібний формат

Крихкість у всьому цьому полягає в кроці перекладу посередині. Ваш файл .po живить як .mo (PHP), так і JSON (JavaScript), тому один невдалий переклад — спотворений %s, зламаний тег <strong>, перейменована форма множини — одночасно псує обидва виходи. І оскільки JS-рядки завантажуються асинхронно в браузері, структурна помилка там часто проявляється як порожня мітка або жорсткий збій, а не як плавне повернення до резерву.

Одне завантаження, PHP та JavaScript охоплено

Саме тут конвеєр перекладів, що розуміє структуру Gettext, займає своє місце. SimplePoTranslate приймає один вихідний файл .po або .pot і створює чистий, перекладений вихід у кількох форматах з одного завантаження.po, .mo, .json, .php та .xliff — тому вам не доведеться з'єднувати окремі інструменти для ваших шарів PHP та JavaScript. Його функція Syntax Locking утримує %s, %1$s, {count} та вбудований HTML на місці, що подвійно важливо для рядків редактора блоків, де зламаний заповнювач може вивести з ладу всю панель редактора. Ми детальніше розглядаємо модель "одне джерело, багато виходів" у статті один файл на вхід, п'ять форматів на вихід.

Ви все одно запускаєте make-json, щоб створити хешовані файли, які очікує WordPress — цей крок є специфічним для WordPress і залишається у вашій збірці. Але сам переклад, частина, яка найімовірніше зламає ваші JS-рядки, обробляється контекстно-орієнтованим рушієм замість скрипта пошуку та заміни.

Висновок

Причина, чому ваш редактор блоків залишається англійською, є структурною, а не помилкою: JSON-переклад WordPress — це окрема система доставки від файлу .mo, створена спеціально тому, що браузери не можуть читати дані Gettext на стороні сервера. Як тільки ви зрозумієте, що рядки JavaScript потребують JSON з MD5-хешем для кожного скрипта, згенерованого за допомогою wp i18n make-json та підключеного через wp_set_script_translations(), виправлення стає механічним. Зберігайте свої рядки в одному .po файлі, скомпільуйте .mo для PHP і запустіть make-json для JS.

Виконайте крок перекладу правильно, і обидва виходи працюватимуть. Зробите помилку, і будете цілий день налагоджувати порожні панелі редактора.

Готові перекладати ваші WordPress JSON та PHP рядки з одного чистого джерела? Спробуйте SimplePoTranslate безкоштовно — кредитна картка не потрібна. Безкоштовний тариф перекладає реальні файли .po та .pot з безпечним для заповнювачів Syntax Locking, тож рядки вашого редактора блоків будуть правильними.

Поділитися цією статтею