1С Битрикс · 6 мин чтения

Языковые файлы Битрикс: локализация компонентов и сообщений

Языковые файлы Битрикс отвечают за то, чтобы текст кнопки, сообщение об ошибке или подсказка в админке подтягивались из php-массива, а не были зашиты прямо в разметку компонента. Когда беру в работу проект на 1С-Битрикс с мультиязычным фронтом или просто с кастомными компонентами, первым делом смотрю, как разложены эти файлы - по ним видно, писал компонент разработчик, который понимает архитектуру ядра, или просто скопировал .default и захардкодил текст в шаблоне.

Структура каталогов lang в компонентах и модулях

Любой компонент, шаблон или модуль в Битрикс хранит переводы в подпапке lang, а внутри неё - в папках с кодом языка: ru, en, при необходимости de, uk и так далее. Главное правило, из-за которого чаще всего путаются новички: имя языкового файла должно точно повторять имя php-файла, для которого он пишет переводы, и лежать по тому же относительному пути.

Файл компонента Языковой файл
component.php lang/ru/component.php
class.php (для комплексных компонентов) lang/ru/class.php
templates/.default/template.php templates/.default/lang/ru/template.php
.description.php (описание компонента в списке) lang/ru/.description.php
.parameters.php (параметры в настройках) lang/ru/.parameters.php

Заметьте: у шаблона своя папка lang внутри templates/имя_шаблона/, отдельная от языковых файлов самого компонента. Это разделение постоянно забывают, и потом удивляются, почему текст в шаблоне не переводится, хотя в component.php всё подключено верно.

Подключение языковых файлов: IncludeModuleLangFile и Loc::loadMessages

В старом ядре (D7 ещё не был обязателен) языковые файлы подключались через IncludeModuleLangFile(__FILE__). Функция рабочая и до сих пор встречается в legacy-компонентах, но с переходом на пространства имён Битрикс продвигает класс BitrixMainLocalizationLoc.

use BitrixMainLocalizationLoc;

Loc::loadMessages(__FILE__);

$arResult['TITLE'] = Loc::getMessage('MY_COMPONENT_TITLE');

Важный нюанс: Loc::loadMessages подгружает языковой файл, соответствующий переданному пути к файлу - не ко всей папке компонента. Если вызвать её в component.php, сообщения из lang-файла шаблона всё равно не станут доступны - там нужен свой вызов, обычно в начале template.php.

Ещё один момент, который экономит время при отладке: если языковой файл для текущего языка сайта отсутствует, ядро автоматически ищет фолбэк в lang/ru (или в языке по умолчанию, заданном в настройках). Но фолбэк работает только если сама папка ru физически существует - пустая директория без файла message-код не найдёт нигде, и вместо текста вы получите пустую строку или код сообщения на странице.

Формат сообщений и плейсхолдеры

Внутри языкового файла лежит обычный php-массив $MESS:

$MESS['CATALOG_ADD_TO_BASKET'] = 'Добавить в корзину';
$MESS['CATALOG_ITEMS_COUNT'] = 'В наличии: #COUNT# шт.';

Плейсхолдеры вида #COUNT# подставляются вторым аргументом при вызове:

echo Loc::getMessage('CATALOG_ITEMS_COUNT', ['#COUNT#' => $arItem['QUANTITY']]);

На практике держусь одного правила по именованию кодов: префикс модуля или компонента плюс смысловое имя - CATALOG_ADD_TO_BASKET, а не MESS1 или TEXT_OK. На проекте, где переводов набирается пара сотен, обезличенные коды превращаются в отдельный квест - приходится открывать файл и искать по контексту, что и где используется. С внятным неймингом это отпадает: код сообщения сам объясняет, откуда он и для чего.

Отдельно слежу за кодировкой: все языковые файлы должны быть в UTF‑8 без BOM, если сайт работает на UTF-8-ядре (актуально для всех новых проектов на D7). На старых сайтах, доставшихся в наследство, иногда встречается windows-1251 - тогда либо весь сайт живёт в этой кодировке, либо файл перекодируется перед подключением, иначе вместо кириллицы вылезут кракозябры именно в тех местах, где текст берётся из lang, а не выводится напрямую из базы.

Бесплатный материал

🎁 Полезный скрипт в подарок

Подпишитесь на Telegram - пришлю готовый скрипт по этой теме.

Без спама. Отписка в 1 клик.

Локализация шаблонов компонентов и .default

Шаблон компонента - отдельная сущность со своим набором языковых файлов, и это осознанное архитектурное решение: один и тот же компонент может использовать несколько шаблонов оформления под разные разделы сайта, и тексты в них могут отличаться (например, в шаблоне для каталога - «Все товары», а в шаблоне для акций - «Все предложения»).

При разработке кастомного шаблона на основе .default я всегда копирую не только template.php и файлы стилей, но и папку lang целиком, а потом уже правлю тексты под задачу. Пропуск этого шага - частая причина, когда кастомный шаблон выводит пустые строки там, где в .default всё работало: система ищет сообщение в lang-папке нового шаблона, а её просто нет.

Локализация внутри style.php и component_epilog.php

Эти файлы часто выпадают из внимания при аудите локализации. style.php обычно не содержит текста, а вот component_epilog.php нередко используется для вывода хлебных крошек, заголовков или meta-тегов - и туда тоже нужен отдельный Loc::loadMessages(__FILE__), если текст берётся из языкового файла, а не формируется динамически из данных инфоблока.

Мультиязычность в кастомных модулях

Если делаете собственный модуль (а не просто компонент), к языковым файлам добавляется ещё один уровень - папка install/index.php и общий lang/ru/.description.php модуля, отвечающий за то, как модуль называется в списке «Модули» в админке. Забытый файл там не вызывает ошибку - модуль просто отображается латиницей по системному имени вместо человекочитаемого названия, что выглядит небрежно при сдаче проекта заказчику.

На практике мультиязычные модули и компоненты с нуля разумно закладывать сразу на этапе проектирования, а не докручивать задним числом - переписывать хардкод текста на Loc::getMessage в уже работающем коде на боевом проекте всегда дольше, чем сделать правильно сразу. Если нужна разработка или доработка сайта на 1С-Битрикс с нормальной структурой языковых файлов и мультиязычностью из коробки, обычно проще один раз обсудить архитектуру с разработчиком, чем потом распутывать смесь захардкоженных строк и Loc::getMessage по всему проекту.

Частые ошибки при работе с языковыми файлами

  • Забыли Loc::loadMessages в template.php. Компонент грузит свои сообщения, а шаблон - нет, потому что это разные вызовы для разных файлов.
  • Кэш компонента хранит уже переведённый текст. Если включено кэширование компонента и вы поменяли текст в lang-файле, старый вариант может отдаваться из кэша до его очистки - на многоязычных сайтах это особенно заметно, когда кэш общий для всех языковых версий без разбивки по LANGUAGE_ID.
  • Смешение $MESS и Loc::getMessage на одном проекте. Оба механизма технически совместимы, но вперемешку это усложняет поддержку - на аудите я обычно советую унифицировать на Loc::getMessage как более актуальный API.
  • Отсутствующий фолбэк-язык. Если сайт мультиязычный, а перевод для нового языка не готов, лучше явно продублировать файл из lang/ru в новую папку языка, а не оставлять пустоту - иначе часть интерфейса просто исчезнет для пользователей этой языковой версии.
  • BOM в начале php-файла с $MESS. Невидимый символ перед <?php ломает вывод заголовков и может привести к ошибке headers already sent - типичная проблема при редактировании lang-файлов в неправильно настроенном редакторе.

Чтобы сайт работал без сбоев

Техподдержка

от 15 000 ₽/мес

Подробнее →

Частые вопросы

Чем IncludeModuleLangFile отличается от Loc::loadMessages?

IncludeModuleLangFile - функция из старого ядра, она подключает языковой файл по прямому пути и до сих пор работает в legacy-компонентах. Loc::loadMessages - актуальный метод из пространства имён BitrixMainLocalization, он же используется во всех современных компонентах ядра. Функционально разница небольшая, но в новых проектах и кастомных компонентах стоит использовать именно Loc, потому что старая функция считается устаревшей и может быть убрана из будущих версий ядра.

Как добавить в Битрикс язык, которого нет среди стандартных ru/en?

Нужно создать языковую версию сайта в настройках (Настройки → Веб-мастеру → Языковые версии), указать её код, а затем для каждого используемого компонента и модуля создать соответствующую папку lang с этим кодом и скопировать туда файлы из lang/ru как основу для перевода. Автоматически новый язык не подтянет тексты - Битрикс просто не найдёт файлы и покажет пустые значения или фолбэк на язык по умолчанию.

Почему после правки текста в языковом файле на сайте ничего не поменялось?

Чаще всего дело в кэше компонента - очистите его через админку (Настройки → Автокэширование → сброс кэша) или удалите папку /bitrix/cache вручную. Реже причина в опечатке в коде сообщения: если код в Loc::getMessage не совпадает с ключом массива $MESS буква в букву, метод вернёт пустую строку без ошибки, и найти проблему на глаз сложно - помогает временный var_dump массива $MESS сразу после подключения файла.

Можно ли подключать языковые файлы не из стандартной папки lang?

Технически да - можно включить любой php-файл с массивом $MESS напрямую через include, минуя Loc и IncludeModuleLangFile. Но тогда теряется автоматический фолбэк на язык по умолчанию и совместимость со стандартными механизмами кэширования локализации, поэтому на практике так делают только для разовых задач вне компонентной модели, а не для полноценных модулей и шаблонов.

Есть задача?

Обсудим в мессенджере

Расскажите, что нужно сделать — отвечу в течение 4 часов в рабочее время. Первая консультация бесплатно.

Самозанятый Калинкин Н. А. · работаю с физлицами и юрлицами

Продолжая пользование настоящим сайтом Вы выражаете своё согласие на обработку Ваших персональных данных (файлов куки) с использованием Yandex.Metrika.
Понятно