1Иерархия языков: Платформа → Тенант → Локация
Каждый уровень — это подмножество языков уровня выше. Нельзя включить на локации язык, которого нет у тенанта.
PLATFORMмастер-реестр · superadmin
Все языки, которые в принципе умеет показывать платформа. Добавление = строка в БД + JSON-файл переводов в репозитории.
en-US
fr-CA
es-MX
de-DE
…
▼ subset
TENANTнапр. Kohler · выбирает superadmin
Какие из языков платформы активны для этого клиента. Тенант-админ видит в CMS/LMS только эти языки.
en-US ★
fr-CA
▼ subset
LOCATIONнапр. Canada Sales · тенант-админ
Какие из языков тенанта доступны на локации + какой дефолтный. NULL = все языки тенанта.
en-CA ★
fr-CA
Пример Kohler Canada. На платформе зарегистрированы английский и французский → у Kohler как у тенанта активированы оба → локация «Montréal Showroom» оставила только fr-CA, а «Canada Sales» — оба, и там у пользователя появится переключатель языка.
2Как платформа решает, какой язык показать пользователю
Идём сверху вниз — первое, что нашлось, побеждает. en-US — финальная страховка.
1
User choice
Пользователь сам кликнул переключатель в шапке
localStorage
2
Segment
Override от сегмента программы (появится после P10)
program_segments
3
Location default
Дефолтный язык локации, где работает пользователь
locations.locale
4
Tenant default
Дефолтный язык клиента (тенанта)
tenant_settings
5
Global fallback
Жёстко зашитый английский — никогда не сломается
en-US
Правило бизнеса. У пользователя нет своего поля «язык» в профиле. Сменил локацию — язык пересчитался автоматически. «Язык — это свойство рабочей среды, а не человека.»
3Где живут сами переводы — это два разных мира
Интерфейсные строки и контент клиента переводятся по-разному и разными людьми.
STATIC UI
Кнопки, лейблы, ошибки
Где
JSON-файлы в коде (fr-CA.json)
Кто переводит
Разработчики и продакт-менеджер
Как доставляется
Только через деплой
Пример
«Save» → «Enregistrer»
DYNAMIC CONTENT
Страницы CMS и курсы LMS
Где
Таблицы БД (cms_content_translations)
Кто переводит
Контент-менеджер тенанта
Как доставляется
Сразу из админки, без деплоя
Пример
«Welcome to Kohler Rewards…» → «Bienvenue chez Kohler…»
Почему так. Кнопка «Save» одинаковая у Kohler и Tesla — Kohler-у не нужно (и нельзя) трогать её перевод. А вот про сантехнику пишет сам Kohler и редактирует это через свою админку. Поэтому два разных хранилища.