SLOT-H: Принцип локализации
В системе локализация разделена на три типа в зависимости от источника текста и способа его перевода. Все они работают по единому принципу: при наличии перевода на текущий язык пользователя показывается перевод, при отсутствии - исходный текст.
1. Текст в коде
Тексты, которые жёстко зашиты в PHP-файлах, передаются через статический метод `\Config\CC::locale(&
039;....')`.
Пример:
php
echo CC::locale('Добро пожаловать');
Для таких текстов существует сборщик, который сканирует код, находит все вызовы CC::locale() и актуализирует список строк для перевода. Эти строки сохраняются в таблицу tkeys.
В полной версии предусмотрен механизм автоматического перевода через API внешних сервисов. Он формирует первичный пул переводов в таблице tvalues. Первичный - потому что машинный перевод требует ручной корректировки, так как качество автоматического перевода недостаточно для production-использования.
Переводы выполняются на все языки, включённые в проекте (таблица project_languages).
Если перевод отсутствует, система возвращает исходный текст, переданный как аргумент в CC::locale().
2. Полноценные тексты
Это тексты, которые хранятся в таблице texts и управляются через административный интерфейс. Для них используется связанная таблица переводов t_texts.
Для таких текстов автоматизированный перевод не применяется. Большие объёмы текста при машинном переводе дают результат, неприемлемый с точки зрения носителей языка. Переводы выполняются вручную через интерфейс администратора.
Структура:
texts - основная таблица с исходными текстами
t_texts - таблица переводов, связанная с texts через поле parent
3. Переводные тексты в хранилище данных
Для таблиц, которые должны поддерживать переводы, в классе DbTable устанавливается свойство:
php
public static $_translate = true;
Для работы с переводами необходимо:
Создать таблицу переводов с именем t_<имя основной таблицы>
В этой таблице обязательно должны быть поля:
language_id - идентификатор языка
parent - идентификатор записи из основной таблицы
Добавить поля, соответствующие переводимым полям основной таблицы (1:1 по именам и типам)
Программисту не нужно думать о JOIN-ах и данных. Его задача - работать с исходной моделью, без использования модели с префиксом t_. ORM автоматически формирует один запрос, получающий исходные данные таблицы и JSON, содержащий полный набор переводов.
Пример для демонстрации принципа:
В административной части вызывается:
php
$links = \Modules\Base\Models\DbTables\Alias::getAll();
ORM генерирует следующий SQL-запрос:
sql
SELECT
aliases.*,
CONCAT(
"{",
GROUP_CONCAT(
CONCAT(
'"',
dev.t_aliases.language_id,
'":{"alias_name":"',
REPLACE(
REPLACE(
REPLACE(
IFNULL(dev.t_aliases.alias_name,''),
'"',
'\\"'
),
'\n',
'<br>'
),
'\r',
''
),
'"}'
)
),
"}"
) AS tblock
FROM
`dev`.`aliases` AS aliases
LEFT JOIN dev.t_aliases ON dev.t_aliases.parent = dev.aliases.alias_id
WHERE dev.aliases.alias_id IS NOT NULL
AND aliases.project_id = "1"
GROUP BY dev.aliases.alias_id
Все переводы собираются в JSON-поле tblock, которое затем парсится моделью. При вызове геттера модель проверяет наличие перевода на текущий язык и возвращает его, если он доступен.
Единый принцип
Во всех трёх случаях действует одно правило:
Если перевод на текущий язык пользователя существует - показывается он. Если нет - показывается исходный текст.
Исходный текст для кода - это аргумент метода CC::locale(). Для данных - это значение в исходной таблице.
Программист работает только с исходными сущностями. Один раз создав таблицу с префиксом t_ и переопределив в классе признак переводной сущности, программист может забыть про переводы. Всё, что связано с JOIN-ами, группировкой и подстановкой переводов, берёт на себя ORM. Это делает систему устойчивой к отсутствию переводов: пользователь всегда видит текст, пусть и не на своём языке.
Что дальше?
- ➡️ Раздел 27. Запуск сервера очередей
- ➡️ Раздел 28. Задачи сервера очередей
- ➡️ Раздел 29. Хелперы