Языковые файлы - сообщения, подстановки, второй язык
Выносим тексты из кода в языковые файлы: чтобы правка формулировки не была правкой логики, а второй язык не был переписыванием модуля.
Решение
Раскладываем файлы рядом с кодом:
/local/modules/vendor.shop/lib/sync.php/local/modules/vendor.shop/lang/ru/lib/sync.php - тексты того же файла/local/modules/vendor.shop/lang/en/lib/sync.php - и его же на втором языке// путь после lang/<язык>/ повторяет путь к файлу с кодомЯзыковой файл находят по пути, а не по имени модуля. Он повторяет путь к файлу с кодом, и файл, положенный не туда, платформа просто не увидит.
Подключаем сообщения и читаем их:
use Bitrix\Main\Localization\Loc;
Loc::loadMessages(__FILE__); // подключаем тексты этого файлаecho Loc::getMessage('VENDOR_SHOP_SYNC_START');// в языковом файле: $MESS['VENDOR_SHOP_SYNC_START'] = 'Обмен запущен';// вызов загрузки ставят один раз, в самом начале файла с кодомКлючи начинают с имени модуля, потому что они общие для всего проекта. Ключ вида
TITLE рано или поздно встретится в чужом файле, и один из двух текстов
проиграет.
Подставляем значения в текст:
echo Loc::getMessage('VENDOR_SHOP_SYNC_DONE', ['#COUNT#' => $count, '#TIME#' => $sec]);// в языковом файле: 'Обработано #COUNT# товаров за #TIME# секунд'// склейка строк вместо замен ломает перевод: порядок слов в языках разный// имена фраз начинают с имени модуля: так они не сталкиваются с чужимиЗначения передают заменами, а не склейкой строк. При переводе порядок слов меняется, и собранная из кусков фраза на другом языке рассыпается в бессмыслицу.
Отдельно кладём тексты компонента:
components/vendor/cart/lang/ru/class.php - тексты кода компонентаcomponents/vendor/cart/lang/ru/.parameters.php - названия параметровcomponents/vendor/cart/templates/.default/lang/ru/template.php - тексты шаблонаУ компонента своя раскладка языковых файлов: отдельно код, отдельно параметры, отдельно шаблон. Текст шаблона в файле кода не найдётся, и наоборот.
Тексты для сотрудников и тексты для покупателей стоит разводить по ключам сразу. Формулировка в административной части живёт годами, а витринную правят к каждой акции, и общий ключ делает эту правку опасной.
Языковой файл читают целиком при первом обращении к нему. Складывать в один файл тексты всего модуля дешевле, чем дробить его на десятки маленьких, каждый со своим обращением к диску.
Второй язык добавляют копированием каталога и переводом значений. Ключи при этом не трогают: расхождение в ключах даёт пропавший текст ровно на том языке, на котором его никто не проверяет.
Типичные проблемы
Вместо текста выводится имя ключа.
Сообщения именно этого файла не подключены вызовом загрузки в самом его начале. Строку загрузки сообщений ставят до первого обращения к любому из этих текстов.
Текст не меняется после правки файла.
Правился языковой файл не того пути или не того языка. Путь после каталога языка повторяет путь к файлу с кодом.
В тексте видны решётки вместо чисел.
Замены не переданы вторым аргументом при чтении сообщения. Подстановки в тексте сообщения работают только через этот второй аргумент вызова чтения.
На втором языке текст остался русским.
Для этого языка нет файла с таким ключом. Платформа в такой ситуации берёт язык по умолчанию.
Тексты шаблона компонента не подхватились.
Они лежат в языковом файле кода, а не шаблона. У шаблона компонента свой собственный каталог языковых файлов рядом с его разметкой.
Частые вопросы
Нужны ли языковые файлы, если сайт один и русский?
Полезны: правка формулировок перестаёт быть правкой кода. Это дешевле, чем кажется на старте.
Как назвать ключ сообщения?
Именем модуля с приставкой и смыслом текста. Ключи общие для всего проекта, и короткие имена конфликтуют.
Где взять список языков сайта?
В настройках сайта: язык задаётся там же, где и остальные его параметры. Код читает текущий язык из окружения.
Можно ли хранить тексты в базе?
Можно, но тогда их правка требует интерфейса и переноса между стендами. Файлы едут вместе с кодом.
Смежное
-
Свой модуль - оглавление подтемы
-
Мастер тиражного решения: шаги, макросы, публичная часть - почему тексты мастера выносят в языковые файлы
-
Свой модуль: структура, установка, автозагрузка - куда кладут языковые файлы
-
Свой компонент: структура, параметры, кэш результата - раскладка файлов компонента
-
Настройки проекта: файл ядра, опции модуля, разные стенды - что хранят не в файлах
-
Модули и решения - устройство модулей целиком
-
Публикация своего модуля: требования, обновления, поддержка - зачем это чужим проектам
-
Второй язык сайта: языки и сайты, тексты шаблона, переключатель - те же файлы в шаблоне сайта
-
Модуль установился, но не работает - пустой пункт меню и незагруженные классы