Транслит в Битрикс: CUtil::translit для CODE и ЧПУ

ЧПУ, символьный код элемента инфоблока, имя файла в /upload/ — в Битрикс для этого обычно берут транслит. Писать свою таблицу замен не нужно: в ядре есть CUtil::translit() (и обёртки вокруг неё в D7-сценариях генерации кода).

Ниже — рабочий вызов, параметры замены пробелов и «мусора», как получить код для URL и какие грабли ловят на кириллических названиях.

Базовый пример

<?php
$name = 'Русский текст в транслит';

$arParams = [
    'replace_space' => '-',
    'replace_other' => '-',
];

$code = CUtil::translit($name, 'ru', $arParams);
// например: russkij-tekst-v-translit

echo $code;

Второй аргумент — язык исходного текста (ru). Третий — массив правил. Для символьного кода элемента чаще ставят дефис и в пробелах, и в прочих символах.

Параметры, которые реально нужны

  • replace_space — чем заменить пробел (- для URL, иногда _).
  • replace_other — чем заменить символы вне латиницы/цифр после транслита (скобки, кавычки, №).
  • change_case — привести регистр (L в нижний — удобно для CODE).
  • max_len — обрезать длинные названия, чтобы CODE не раздувал URL и индекс.
  • safe_chars — какие символы оставить без замены (осторожно с точкой и слэшем).
<?php
$code = CUtil::translit($name, 'ru', [
    'replace_space' => '-',
    'replace_other' => '-',
    'change_case' => 'L',
    'max_len' => 100,
]);

Символьный код элемента инфоблока

При добавлении элемента через API не забывайте уникальность CODE в инфоблоке:

<?php
use Bitrix\Main\Loader;

Loader::includeModule('iblock');

$base = CUtil::translit($title, 'ru', [
    'replace_space' => '-',
    'replace_other' => '-',
    'change_case' => 'L',
    'max_len' => 80,
]);

$code = $base;
$i = 0;
while (CIBlockElement::GetList(
    [],
    ['IBLOCK_ID' => $iblockId, '=CODE' => $code],
    false,
    ['nTopCount' => 1],
    ['ID']
)->Fetch()) {
    $i++;
    $code = $base . '-' . $i;
}

$el = new CIBlockElement();
$id = $el->Add([
    'IBLOCK_ID' => $iblockId,
    'NAME' => $title,
    'CODE' => $code,
    'ACTIVE' => 'Y',
]);

Для выборок и фильтров по свойствам см. также фильтры GetList.

Типичные грабли

  • Опечатка Cutil. Класс — CUtil (U заглавная). В старых сниппетах часто пишут неправильно.
  • Пробел в replace_space. Если оставить пробел, CODE с пробелами сломает URL и ЧПУ.
  • Пустая строка на входе. Транслит от пустого NAME даст пустой CODE — элемент сохранится криво; проверяйте до записи.
  • Дубли CODE. Два «Красное платье» без суффикса — конфликт; нужен цикл уникальности выше.
  • Смешение правил в одном проекте. Где-то дефис, где-то подчёркивание — ад для редиректов и SEO. Зафиксируйте один helper.

Небольшой helper в local/

<?php
namespace Local\Helper;

final class Translit
{
    public static function code(string $text, int $maxLen = 100): string
    {
        $text = trim($text);
        if ($text === '') {
            return '';
        }

        return \CUtil::translit($text, 'ru', [
            'replace_space' => '-',
            'replace_other' => '-',
            'change_case' => 'L',
            'max_len' => $maxLen,
        ]);
    }
}

Так транслит не разъедется по проекту. Если сервис тяжёлый и вызывается из событий — его же можно повесить рядом с DI, см. ServiceLocator.

Вывод

Для транслита в Битрикс достаточно CUtil::translit() с дефисами, нижним регистром и ограничением длины. Оберните вызов в один helper, проверяйте уникальность CODE и не оставляйте пробелы в URL. Так ЧПУ и символьные коды остаются предсказуемыми на всём проекте.