Языки
Многоязычный контент живёт в трёх таблицах: сами языки, переводы и переводчики, которые эти переводы наполняют.
Строки интерфейса — отдельная история, это лексиконы, их читает lang(). Здесь речь про контент.
Язык
Строка в PageBlocks → Языки.
| Поле | Что это |
|---|---|
key | Короткий код, которым язык называется в коде — en, ru, de |
name | Название для человека |
culture_key | Culture key MODX |
locale | Системная локаль, для форматирования дат и чисел |
url_prefix | Префикс в адресе. У основного языка пуст |
is_default | Язык, на который всё откатывается |
translator_id | Какой переводчик наполняет этот язык |
published_at | Неопубликованный язык для фронта не существует |
Один язык — никакой многоязычности
Многоязычный режим включается, только когда опубликованных языков больше одного. Один язык не стоит ничего: ни префиксов, ни разрешения адреса, ни лишних запросов.
Префиксы и адреса
У основного языка префикса нет. Это намеренная асимметрия: существующий одноязычный сайт сохраняет все свои адреса, когда к нему добавляют второй язык, и ничего не нужно переадресовывать.
/about основной язык
/en/about дополнительныйЯзык определяется по префиксу в адресе; если ни один не совпал, берётся основной.
Сборка адреса живёт в одном месте, поэтому правило одно, а не по одному на каждый вызов: и хелпер lang_url(), и модификатор route идут через один резолвер. Он идемпотентен — адрес, у которого префикс уже есть, не получит его второй раз. Это важно, потому что вызывающий обычно не знает: откуда-то приходит голый URI, откуда-то уже с префиксом.
Переводы
Хранятся по языкам в pb_translations, привязка — владелец (model_type + model_id) и контекст.
Поля ресурса лежат явными колонками: pagetitle, longtitle, description, introtext, content, menutitle, alias, uri. Поля конструктора едут в data строки — так же, как и у самого объекта.
Нет перевода — показывается оригинал
Поле без перевода откатывается на исходный текст, а не выводится пустым. Поэтому недоделанный перевод никогда не опустошает страницу — но из этого же следует, что непереведённый сайт выглядит работающим, так что проверять надо охват, а не внешний вид.
Чем наполнять
Руками в менеджере или автоматически: назначьте языку переводчика, и компонент сам сходит в API провайдера. Драйверы, промпты, стоимость и поведение при сбоях — на странице Переводчики.
Копирование между языками
Блоки можно копировать из одного языка в другой — см. Копирование.