Переводы
Виджет Shoutbox, его право доступа и его ссылка навигации прямо сейчас показывают захардкоженный английский. На этой странице мы переносим этот текст в файлы локалей, чтобы Shoutbox говорил на каждом языке, на котором говорит ваш сервер — и чтобы заголовок его права доступа и строки журнала активности показывали настоящие слова вместо сырых ключей.
Полный справочник: Локализация.
А это вообще обязательно?
Да, хотя бы немного. Вы можете захардкодить английский в своих Svelte-компонентах — но двум видам текста больше негде жить: заголовки прав доступа (страница «Права доступа» в панели) и строки журнала активности (страница «Активность») могут браться только из файлов локалей. Так что даже англоязычному аддону нужен en-US.json.
Шаг 1 — настройте файлы локалей
Текст живёт в JSON-файлах в папке src/main/resources/locales/, по одному файлу на язык, а имя файла — это код языка:
src/main/resources/locales/
├─ en-US.json ← required; also the fallback
├─ tr.json
└─ ru.jsonОбязателен только en-US.json. Создайте его сейчас, содержащим просто {}, если его ещё нет.
en-US — это подстраховка
Если ключ отсутствует для языка посетителя, Pano откатывается к en-US.json. Если его нет и там тоже, посетитель видит на экране сырой путь ключа (вроде plugins.pano-plugin-shoutbox.widget.title). Держите en-US.json полным — сырой ключ на экране это ваш первый признак, что это не так. Также сохраняйте каждый файл в UTF-8, иначе турецкие/русские символы превратятся в кашу вроде ö.
Шаг 2 — пространство имён, в одном предложении
Pano отдаёт каждый написанный вами ключ под plugins.<pluginId>.<key>. Для Shoutbox этот префикс — plugins.pano-plugin-shoutbox.. Вы никогда не пишете этот префикс — в вашем JSON ключи остаются короткими (widget.title), а Pano добавляет префикс автоматически. Именно это удерживает ваши ключи от столкновений с ключами ядра платформы или другого аддона.
Единственное место, где префикс действительно написан, — маленький хелпер, который шаблон уже поставляет в main.js:
export const _ = derived(i18n, ($t) => (key, options) => $t(`plugins.${pluginId}.${key}`, options));Скопируйте его как есть; чтобы им пользоваться, понимать его не нужно.
Шаг 3 — определите первые ключи
Поместите текст вашего UI в en-US.json, вложенный как вам угодно. Вложенные объекты становятся путями через точку, а {...} отмечает плейсхолдер, который вы заполните позже:
{
"widget": {
"title": "Latest shouts",
"empty": "No shouts yet — be the first!"
},
"nav": {
"shoutbox": "Shoutbox"
}
}Шаг 4 — используйте ключи в компоненте
Импортируйте хелпер _ из вашего main.js и читайте его с префиксом $:
<script>
import { _ } from '../main.js';
</script>
<h2>{$_('widget.title')}</h2>{$_('widget.title')} ищет для вас plugins.pano-plugin-shoutbox.widget.title. Чтобы заполнить плейсхолдер, передайте значения вторым аргументом: $_('welcome-message', { values: { username: 'Ada' } }).
Исправьте ../ под глубину вашего файла
import { _ } from '../main.js' предполагает, что ваш компонент лежит ровно на одну папку ниже main.js. В более глубоко вложенном маршруте добавьте больше ../ (вроде ../../main.js), иначе импорт отдаст 404.
Контрольная точка: живая перезагрузка доказывает себя
При включённом режиме разработки и запущенном bun run dev виджет теперь отрисовывает Latest shouts. Теперь отредактируйте строку в en-US.json, сохраните и нажмите F5 — новый текст появляется без пересборки. В этом и выгода режима разработки: Pano читает ваши locales/*.json вживую с диска на каждый запрос. (При выключенном режиме разработки, или в выпущенном jar, локали читаются изнутри jar — чтобы увидеть изменение, пришлось бы пересобирать и перезапускать.)
Шаг 5 — переведите право доступа и журнал активности
Эти два раздела приходят не из ваших компонентов — Pano читает их напрямую, чтобы заполнить страницы «Права доступа» и «Активность» в панели. Оба лежат в корне файла, рядом с вашими собственными ключами.
Имена ключей выводятся из имён ваших Kotlin-классов, так что вы их не выбираете:
- Право доступа
ManageShoutboxPermission→ отбросьтеPermission, UPPER_SNAKE →MANAGE_SHOUTBOX. - Журнал активности
CreatedShoutLog→ отбросьтеLog, UPPER_SNAKE →CREATED_SHOUT.
{
"permissions": {
"MANAGE_SHOUTBOX": {
"title": "Manage Shoutbox",
"description": "Allows managing shouts shown on the home page."
}
},
"activity-logs": {
"CREATED_SHOUT": "<b>{username}</b> posted a shout: {target}."
}
}Плейсхолдеры {username} и {target} заполняются из полезной нагрузки details записи журнала (собранной в Kotlin-классе). HTML вроде <b> работает только в строках журнала активности — страница «Активность» отрисовывает их как HTML; обычные ключи, показанные через {$_(...)}, его экранируют.
Контрольная точка
Откройте Панель → Права доступа — ваша запись теперь читается как Manage Shoutbox вместо сырого MANAGE_SHOUTBOX. Опубликуйте выкрик, затем откройте Панель → Активность — предложение появляется с именем пользователя жирным.
Шаг 6 — добавьте ещё один язык
Вы не ограничены английским. Добавьте файл, имя которого — код локали — турецкий в tr.json, русский в ru.json — с теми же ключами, переведёнными:
{
"widget": {
"title": "Son bağırışlar",
"empty": "Henüz bağırış yok — ilk sen ol!"
}
}Любой ключ, который вы не перевели, откатывается к en-US.json, так что частичный перевод никогда не показывает сырой ключ. Чтобы протестировать ваш tr.json, переключите собственный язык на турецкий в Панель → Настройки → Платформа → Предпочтения (или через селектор языка сайта) и обновите.
Администраторы могут переводить за вас
Администраторы могут переопределить любой ключ или добавить целый новый язык прямо из панели, не трогая ваш jar — и их правки переживают обновления аддона. Переопределение администратора всегда побеждает текст из вашего jar, так что кастомная формулировка владельца сайта никогда не будет молча перезаписана обновлением.
Один полный en-US.json
Вот как фрагменты складываются вместе — собственные ключи, permissions и activity-logs, все в корне:
{
"widget": {
"title": "Latest shouts",
"empty": "No shouts yet — be the first!"
},
"nav": { "shoutbox": "Shoutbox" },
"permissions": {
"MANAGE_SHOUTBOX": {
"title": "Manage Shoutbox",
"description": "Allows managing shouts shown on the home page."
}
},
"activity-logs": {
"CREATED_SHOUT": "<b>{username}</b> posted a shout: {target}."
}
}Сломанный JSON-файл ломает все свои ключи
JSON строг: одна лишняя запятая, случайный комментарий или незакрытая скобка делают весь файл невалидным, и тогда ни один его ключ не разрешается — вы увидите сырые пути ключей сразу по всей странице. Если такое случилось, в первую очередь подозревайте синтаксическую ошибку JSON и прогоните файл через любой валидатор.
Shoutbox теперь и выглядит как надо, и говорит на языке. Осталось только упаковать его и поделиться с миром.
Далее: Выпуск →