Bitrix localization
Skill bxmaximum/bitrix-framework-skills/skills/bitrix-localization
AI-скиллы для Bitrix Framework (D7): ORM, контроллеры, роутинг, кеш, безопасность. npx skills add bxmaximum/bitrix-framework-skills. Открытый проект сообщества BXMax.
npx -y skills add bxmaximum/bitrix-framework-skills --skill bitrix-localizationAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
3 things to look at
- 20 days oldThe repository was created 20 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 13 stars13 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Covers Bitrix localization — Bitrix\Main\Localization\Loc, lang/<code/>/ language files, loadMessages, placeholders in getMessage, Context::getCulture() and culture formats, JS localization via BX.message and $Bitrix.Loc, translate:index for phrase indexing. Applied when adding and translating phrases, working with multi-language sites, JS translations in components and templates. Key terms — Loc, getMessage, lang file, Culture, BX.message, loadMessages, i18n.
SKILL.md
7.7 KB, as published. Nobody here has run it
Localization
Baseline: main 23.0+.
Language File
- Encoding UTF-8 without BOM.
- Translation file name matches the name of the PHP file it accompanies.
- Folder:
.../lang/<lang>/<...>mirrors the structure of the main code.
/local/modules/vendor.module/lib/Application/Service/PostService.php
/local/modules/vendor.module/lib/Application/Service/lang/ru/PostService.php
/local/modules/vendor.module/lib/Application/Service/lang/en/PostService.php
Content:
<?php
$MESS['VENDOR_MODULE_POST_PUBLISHED'] = 'Post #NAME# published';
$MESS['VENDOR_MODULE_POST_EMPTY_TITLE'] = 'Post title is empty';
Prefix rules: <VENDOR>_<MODULE>_<CONTEXT>_<CODE> — a short unique key. Without a prefix, conflicts with other modules are likely.
Loc::getMessage and Loading Phrases
use Bitrix\Main\Localization\Loc;
Loc::loadMessages(__FILE__); // knowing where we are — the kernel will find the translation file
echo Loc::getMessage('VENDOR_MODULE_POST_PUBLISHED', ['#NAME#' => $post->getTitle()]);
echo Loc::getMessage('VENDOR_MODULE_POST_PUBLISHED', ['#NAME#' => 'x'], 'en');
- Signature:
Loc::getMessage(string $code, ?array $replace = null, ?string $language = null). - Substitutions — via
#PLACEHOLDER#templates (historical convention). Keys in$replace— with hash marks. $language— language ID (ru,en). If not passed — current site language.
Loc::loadMessages(__FILE__) resolves the neighboring lang/<lang>/<same_file>.php from the caller path. Loc::loadLanguageFile($path) loads phrases for an arbitrary PHP file path (when the mapping is not “same name next to __FILE__”).
When Explicit Loading is Needed
For components, component templates, site templates, and Bitrix admin files, the kernel will automatically include neighboring lang/<lang>/<same_file>.php. Manually call Loc::loadMessages(__FILE__) if:
- The file is outside the standard structure (e.g.,
/local/php_interface/). - You have your own loader/class — each file must itself include its translations, otherwise lazy loading will break.
Arbitrary File
Loc::loadLanguageFile($_SERVER['DOCUMENT_ROOT'] . '/local/php_interface/custom.php');
Module Default Language
$lang = Loc::getDefaultLang(LANGUAGE_ID); // fallback from language settings: 'ru' → 'ru', 'ua' → 'ru'
Use this when forming language package names if the project language is broader than those supported in the module (ua, kz → "fall back" to ru).
Lazy Loading and BX_MESS_LOG
The kernel loads a language file only upon the first getMessage(...) call from it — the "PHP file ↔ language file" mapping must be strict. If a getMessage('FOO_BAR') call comes from one file while the phrase is defined in another, the kernel will start scanning all files — this slows things down.
Diagnostics: enable in /local/php_interface/init.php:
define('BX_MESS_LOG', $_SERVER['DOCUMENT_ROOT'] . '/var/log/bitrix/mess.log');
The log will contain entries like:
[ru]SOME_MESSAGE: not found for /path/to/file.php
CTranslateUtils::CopyMessage('DEMO_CODE', '/path/a.php', '/path/b.php');
How to fix:
- Copy the phrase to the language file of the module/code where the
getMessagecall originates. - Rename the code to something unique if it conflicts with the kernel.
- Move the code to the correct file if it physically ended up in the wrong place.
Do not copy automatically — you might duplicate phrases; investigate the cause.
Regional Settings (Culture)
Date/time/name formats are retrieved from Bitrix\Main\Context\Culture:
$culture = \Bitrix\Main\Context::getCurrent()->getCulture();
$culture->getDateTimeFormat(); // 'DD.MM.YYYY HH:MI:SS'
$culture->getDateFormat(); // 'DD.MM.YYYY'
$culture->getShortTimeFormat(); // 'HH:MI'
$culture->getNameFormat(); // '#LAST_NAME# #NAME# #SECOND_NAME#'
$culture->getNumberDecimals();
$culture->getNumberDecSeparator();
$culture->getNumberThousandsSeparator();
Formatting:
use Bitrix\Main\Type\DateTime;
$date = new DateTime();
echo $date->format($culture->getDateTimeFormat());
// Via classic helpers:
echo \FormatDate($culture->getDateFormat(), $date->getTimestamp());
echo \CurrencyFormat(1234.5, 'RUB');
Language setup: Settings → Product Settings → Language Parameters (date/time/name formats are set per site language). If a component is configured for its own format — it will take precedence.
Setting Phrases in JavaScript
PHP code publishes phrases in BX.message(...):
\Bitrix\Main\Page\Asset::getInstance()->addString(
'<script>' . \Bitrix\Main\Web\Json::encode([
'VENDOR_POST_SAVE' => Loc::getMessage('VENDOR_POST_SAVE'),
'VENDOR_POST_CANCEL' => Loc::getMessage('VENDOR_POST_CANCEL'),
]) . '</script>'
);
Or — more idiomatically — via a JS extension in config.php:
return [
'js' => 'script.js',
'css' => 'style.css',
'rel' => ['main.core'],
'lang_additional' => [
'VENDOR_POST_SAVE', 'VENDOR_POST_CANCEL',
],
];
BX.message('VENDOR_POST_SAVE');
BX.message({ VENDOR_POST_DYNAMIC: 'Loaded asynchronously' });
const welcome = BX.message('WELCOME_TEXT').replace('#NAME#', userName);
BitrixVue 3
// template
<button>{{ $Bitrix.Loc.getMessage('UI_BUTTON_SAVE') }}</button>
// with replacement + reactivity
{{ $Bitrix.Loc.getMessage('DEMO_COUNTER', { '#COUNTER#': this.counter }) }}
// programmatically
this.$Bitrix.Loc.setMessage({ DEMO_COUNTER: 'Counter: #COUNTER#' });
// optimization for heavy templates — (vueInstance, phrasePrefix, phrases?)
import { BitrixVue } from 'ui.vue3';
computed: {
localize() { return BitrixVue.getFilteredPhrases(this, 'MYCOMP_'); }
}
translate:index Command
php bitrix/bitrix.php translate:index
Indexes language files so that the Settings → Localization → View Files page works (CSV export/import, package building). Run this after bulk adding new phrases to a module.
Multilingual Modules
- Store phrases in
lang/ru/,lang/en/,lang/de/— in the root of the PHP file that uses them. - In the module's
install/index.php, include translations:Loc::loadMessages(__FILE__). - Use
Loc::getDefaultLang(LANGUAGE_ID)to "fall back" to the module's base language (ru) ifkz/uais missing. - Publish language names in the system via the Interface Languages form — it cannot be set from
.settings.php.
Antipatterns
- Hardcoding strings in services/controllers.
Errormessage texts should be viaLoc::getMessage. getMessage('CODE')in one file when the phrase is defined in another → scanning all files, slowdown.- Copying phrases between modules via
BX_MESS_LOGwithout analysis — risk of duplication and confusion. - Outputting dates via
date('d.m.Y')instead ofCulture::getDateFormat()— breaks multilingual projects. - Mixing UTF-8 and CP1251 in
lang/— Bitrix will "re-convert" and you'll get garbled text. - JS phrases written as strings from PHP without
htmlspecialcharsbxfor headers going into attributes.
Set default_language in .settings.php for kernel default. BitrixVue 3 localization: skill bitrix-vue.