ВозможностиПлагинЦеныРесурсы
Изменить язык
РесурсыПеревод JSON в WordPress: Переводим JavaScript для редактора блоков

Перевод JSON в WordPress: Переводим JavaScript для редактора блоков

SimplePoTranslate Team27 мая 2026 г.
Перевод JSON в WordPress: Переводим 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, привязанного к этому конкретному идентификатору скрипта. Если вы этого не настроили, вызовы __() в JS просто вернут исходный английский текст — бесшумно, без ошибок в консоли.

Подключение 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, который мы рассматриваем в переводе JSON i18next в 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. Его Блокировка синтаксиса удерживает %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.

Правильно выполните шаг перевода, и оба вывода будут корректными. Ошибитесь, и будете отлаживать пустые панели редактора весь день.

Готовы переводить свои JSON- и PHP-строки WordPress из одного чистого источника? Попробуйте SimplePoTranslate бесплатно — кредитная карта не требуется. Бесплатный тариф переводит настоящие файлы .po и .pot с безопасной блокировкой синтаксиса для заполнителей, чтобы строки вашего редактора блоков были отправлены правильно.

Поделиться этой статьёй