Lang::get и LANG_VAR

Основной способ вывести фразу.

Сигнатура

\mrLexndr\Translate\Lang::get(
    string $code,
    array|string $replace = [],
    bool $forceRaw = false,
    ?string $fallback = null
): string

LANG_VAR() — короткая обёртка над ним, объявленная глобально. В шаблонах удобнее она:

<?= LANG_VAR('HEADER_PHONE', [], false, '+7 000 000-00-00') ?>

Подстановка переменных

Второй аргумент — массив замен. Ключи в тексте фразы пишутся в решётках:

// В словаре: «Осталось #COUNT# дней»
LANG_VAR('DAYS_LEFT', ['#COUNT#' => 5]);

Так текст остаётся целым, и переводчик видит фразу целиком, а не два обрубка, склеенных в коде. Это важнее, чем кажется: в других языках порядок слов другой, и склейка вида LANG_VAR('LEFT') . $n . LANG_VAR('DAYS') не переводится в принципе.

Сырой режим — третий аргумент

В режиме правки на сайте фраза оборачивается в элемент разметки, иначе по ней нельзя было бы кликнуть. Значит, в некоторых местах выводить её как есть нельзя:

Во всех этих местах передавайте true третьим аргументом:

<input placeholder="<?= LANG_VAR('SEARCH_PLACEHOLDER', [], true) ?>">

Без этого разметка разъедется, причём только у администратора с включённым режимом правки — а значит, обнаружится поздно.

Чтение без автосоздания

Lang::get() заводит фразу, если её нет. Обычно это удобно, но не всегда: иногда нужно просто узнать, есть ли перевод, и не мусорить в словаре.

\mrLexndr\Translate\Lang::peek($code);

peek() читает и возвращает то, что нашёл, ничего не создавая. Он нужен там, где код фразы приходит из данных, а не из шаблона: например, при подстановке названий сущностей магазина. Иначе первый же показ страницы с незнакомым идентификатором завёл бы в словаре фразу-пустышку.

Код языка, если вы передаёте его явно, проверяется на входе: из него собирается имя файла кеша словаря, и подставлять туда значение из запроса как есть нельзя. На рабочих проектах это ничего не меняет — коды языков в Битриксе двухсимвольные.

Дедупликация внутри запроса

Если один и тот же новый код встретился на странице несколько раз — в шапке и в подвале, — в базу уйдёт одно обращение, а не два. Модуль помнит, для каких пар «язык и код» он уже вызывал создание в рамках текущего запроса.

Служебные фразы: префикс SYS_

Названия чужих сущностей — свойств инфоблока, платёжных систем, единиц измерения — тоже живут в словаре, но по своей конвенции: SYS_<СУЩНОСТЬ>_<ID>_<ПОЛЕ>, например SYS_IBPROP_123_NAME.

Префикс SYS_ зарезервирован. Lang::get() и импорт CSV новый код с ним не создают: автосоздание при первом показе дало бы фразу с текстом-заглушкой, и сборщик потом принял бы её за свою. Отказ пишется в журнал и показывается в отчёте импорта. Уже существующую служебную фразу импорт по-прежнему обновляет — так их и переводят.

Если такой код нужен вам самим, дайте фразе другое имя.

Заводит служебные фразы отдельный сборщик, а не первый показ страницы. Кнопка, которая его запускает, — на экране Обслуживание.

Цена роста словаря

Словарь кешируется файлом, который читается на каждом запросе страницы. Значит, лишние фразы — это время отклика сайта.

Ориентир: до пяти тысяч фраз словарь читается за единицы миллисекунд и вопросов не вызывает. После десяти тысяч стоит посмотреть на замеры и подумать о разделении словаря по назначению. Точные значения зависят от сервера, поэтому порог здесь — ориентир, а не правило.