agentsclimarketplace

Bitrix localization

Skill bxmaximum/bitrix-framework-skills/skills/bitrix-localization

AI-скиллы для Bitrix Framework (D7): ORM, контроллеры, роутинг, кеш, безопасность. npx skills add bxmaximum/bitrix-framework-skills. Открытый проект сообщества BXMax.

Install
npx -y skills add bxmaximum/bitrix-framework-skills --skill bitrix-localization

Assembled 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 getMessage call 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) if kz/ua is 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. Error message texts should be via Loc::getMessage.
  • getMessage('CODE') in one file when the phrase is defined in another → scanning all files, slowdown.
  • Copying phrases between modules via BX_MESS_LOG without analysis — risk of duplication and confusion.
  • Outputting dates via date('d.m.Y') instead of Culture::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 htmlspecialcharsbx for headers going into attributes.

Set default_language in .settings.php for kernel default. BitrixVue 3 localization: skill bitrix-vue.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.