Архитектура поддержки переводов интерфейсов на другие языки для wordpress в целом и в связке с React
Ниже — полная архитектура переводов в WordPress:
1️⃣ как это работает в целом
2️⃣ как это работает в PHP
3️⃣ как это работает в React / Gutenberg
4️⃣ как соединяются PHP + JS переводы
5️⃣ как это обычно делают профессиональные плагины.
1. Общая архитектура переводов в WordPress
Система переводов в WordPress состоит из 4 уровней:
код → POT → PO → MO / JSON
1️⃣ Код
В коде используются функции:
PHP:
__()
_e()
_n()
_x()
JS:
wp.i18n.__()
wp.i18n._n()
wp.i18n._x()
2️⃣ POT (template)
.pot — шаблон переводов.
Пример:
nv-seo.pot
Он содержит все строки из кода.
3️⃣ PO
Файл конкретного языка:
ru_RU.po
de_DE.po
fr_FR.po
Пример:
msgid "Save settings"
msgstr "Сохранить настройки"
4️⃣ MO / JSON
WordPress использует:
| тип | для |
|---|---|
| MO | PHP |
| JSON | JavaScript |
2. Архитектура переводов для PHP
структура плагина
plugin
├─ languages
│ ├─ nv-seo.pot
│ ├─ nv-seo-ru_RU.po
│ ├─ nv-seo-ru_RU.mo
│
├─ nv-seo.php
подключение textdomain
add_action('plugins_loaded', function () {
load_plugin_textdomain(
'nv-seo',
false,
dirname(plugin_basename(__FILE__)) . '/languages'
);
});
использование
__('Settings saved', 'nv-seo')
или
echo __('Save', 'nv-seo');
3. Архитектура переводов для React / JS
В React используется пакет:
@wordpress/i18n
(глобально это wp.i18n)
использование
import { __ } from '@wordpress/i18n';
__('Save settings', 'nv-seo')
пример React
import { __ } from '@wordpress/i18n';
import { Button } from '@wordpress/components';
export default function SaveButton() {
return (
<Button variant="primary">
{__('Save settings', 'nv-seo')}
</Button>
);
}
4. Как WordPress переводит JS
WordPress не использует MO для JS.
Он использует:
JSON
пример:
languages/nv-seo-ru_RU-3a4f2.json
5. Связка PHP и JS
Очень важная функция:
wp_set_script_translations()
Она говорит WordPress:
"подключи JSON переводы для этого JS файла"
пример
wp_enqueue_script(
'nv-seo-admin',
plugins_url('build/index.js', __FILE__),
['wp-i18n', 'wp-element', 'wp-components'],
'1.0',
true
);
wp_set_script_translations(
'nv-seo-admin',
'nv-seo',
plugin_dir_path(__FILE__) . 'languages'
);
6. Как формируется JSON
WordPress CLI генерирует его из PO.
wp i18n make-json languages
Результат:
nv-seo-ru_RU-xxxx.json
7. Полная структура современного плагина
nv-seo
│
├─ src
│ └─ index.js
│
├─ build
│ └─ index.js
│
├─ languages
│ ├─ nv-seo.pot
│ ├─ nv-seo-ru_RU.po
│ ├─ nv-seo-ru_RU.mo
│ ├─ nv-seo-ru_RU-xxxx.json
│
├─ nv-seo.php
└─ package.json
8. Поток разработки
1️⃣ пишем код
PHP:
__('Save settings', 'nv-seo')
JS:
__('Save settings', 'nv-seo')
2️⃣ генерируем POT
wp i18n make-pot . languages/nv-seo.pot
3️⃣ создаём переводы
ru_RU.po
через:
-
Poedit
-
Loco Translate
4️⃣ компилируем
PO → MO
5️⃣ генерируем JSON
wp i18n make-json languages
9. Как делают крупные плагины
Например:
-
Yoast SEO
-
Rank Math
-
WooCommerce
используют:
languages/
build/
src/
и WordPress i18n CLI.
10. Лучшие практики
всегда указывайте textdomain
__('Save', 'nv-seo')
не используйте динамические строки
❌ плохо
__(text, 'nv-seo')
используйте sprintf
sprintf(
__('Found %d errors', 'nv-seo'),
count
)
используйте контекст
_x('Post', 'noun', 'nv-seo')
11. Очень важная оптимизация "Code splitting"
Если ваш интерфейс React большой, лучше:
code splitting
тогда JSON будет загружаться по частям.
Code splitting — это разбиение большого JavaScript-бандла на несколько файлов, которые загружаются только тогда, когда они реально нужны.
В WordPress это особенно полезно для React-интерфейсов в админке, чтобы не грузить весь JS сразу.
В сборке через @wordpress/scripts code splitting уже поддерживается, потому что внутри используется Webpack.
1. Основная идея
Без code splitting:
index.js
↓
build/index.js (400 KB)
С code splitting:
index.js
↓
build/index.js
build/settings.js
build/schema.js
build/faq.js
Подгружается только нужный модуль.
2. Как это делается в React
Используется dynamic import().
обычный импорт
import SettingsPage from './settings';
всё попадает в один файл.
dynamic import
const SettingsPage = import('./settings');
Webpack создаст отдельный chunk.
Но в React правильнее использовать React.lazy.
3. Пример code splitting
структура
src
├─ index.js
├─ pages
│ ├─ dashboard.js
│ ├─ schema.js
│ └─ settings.js
index.js
import { lazy, Suspense } from '@wordpress/element';
import { Spinner } from '@wordpress/components';
const Dashboard = lazy(() => import('./pages/dashboard'));
const Settings = lazy(() => import('./pages/settings'));
export default function App() {
return (
<Suspense fallback={<Spinner />}>
<Dashboard />
</Suspense>
);
}
4. Что создаст сборка
После
npm run build
в папке build будет:
build
├─ index.js
├─ dashboard.js
├─ settings.js
5. Как WordPress загружает chunks
Важный момент.
WordPress должен знать путь:
wp_enqueue_script(
'nv-seo-admin',
plugins_url('build/index.js', __FILE__),
['wp-element','wp-components','wp-i18n'],
'1.0',
true
);
Webpack автоматически будет подгружать:
build/dashboard.js
build/settings.js
через
import()
6. Как это выглядит в браузере
Без splitting:
index.js 400KB
Со splitting:
index.js 80KB
settings.js 100KB
schema.js 120KB
faq.js 100KB
7. Где это особенно полезно
ВНапример вашемв SEO-плагине можно разделить:
src
├─ index.js
├─ pages
│ ├─ dashboard.js
│ ├─ schema.js
│ ├─ sitemap.js
│ └─ redirects.js
Пользователь открывает Schema → грузится только:
schema.js
8. Пример с роутингом
Если используется **React Router:
const Settings = lazy(() => import('./pages/settings'));
const Schema = lazy(() => import('./pages/schema'));
9. Очень полезная оптимизация
Можно разбить даже библиотеки.
Например:
schema-builder.js
грузить только при редактировании Schema.
10. Важный момент для WordPress
Чтобы chunks работали, build папка должна содержать все файлы:
build
├─ index.js
├─ index.asset.php
├─ 234.js
├─ 567.js
WordPress автоматически подхватывает зависимости из:
index.asset.php
11. Подключение через asset
Правильный способ:
$asset = include plugin_dir_path(__FILE__) . 'build/index.asset.php';
wp_enqueue_script(
'nv-seo-admin',
plugins_url('build/index.js', __FILE__),
$asset['dependencies'],
$asset['version'],
true
);
12. Итог по "Code splitting"
Code splitting позволяет:
✔ ускорить загрузку
✔ уменьшить первый бандл
✔ грузить код по требованию
Это стандартная практика для:
-
Yoast SEO
-
WooCommerce
-
Rank Math
12. Типичная проблема новичков
Они думают:
JSON перевод нужно писать вручную.
Нет.
Он генерируется автоматически.
13. Самая правильная архитектура для вашего SEO-плагина
nv-seo
├─ src
│ └─ admin
│ └─ index.js
│
├─ build
│ └─ admin.js
│
├─ languages
│ ├─ nv-seo.pot
│ ├─ nv-seo-ru_RU.po
│ ├─ nv-seo-ru_RU.mo
│ ├─ nv-seo-ru_RU.json
│
└─ nv-seo.php