Транслитерация возвращает красивую строку, но два товара получают одинаковый CODE. Цена ошибки — дубли адресов, неверная карточка и необходимость чинить старые ссылки.
Исходная функция `CUtil::translit` остаётся хорошей точкой входа. Редактура добавляет три обязательных слоя: нормализацию результата, проверку уникальности и правило поведения при смене уже опубликованного кода.
Что сохраняем из исходной заметки
Часто в Bitrix необходимо сгенерировать код элемента из имени. Привожу пример реализации именно такой функции с помощью функции Bitrix API для транслита CUtil::translit:
function strToElementCode($str, $maxLength = 100) {
$params = array(
"max_len" => $maxLength,
"change_case" => "L",
"replace_space" => "_",
"replace_other" => "_",
"delete_repeat_replace" => "true",
"use_google" => "false",
);
return CUtil::translit($str, "ru", $params);
}
Как использовать функцию безопасно
Транслитерация имени удобна, но код элемента должен оставаться уникальным. Поэтому после генерации проверяйте существующие символьные коды в инфоблоке и при совпадении добавляйте числовой суффикс. Иначе два товара с похожим названием могут получить один URL.
telefon-samsung
telefon-samsung-2
telefon-samsung-3
Также стоит сразу нормализовать результат: привести к нижнему регистру, заменить пробелы на дефис, убрать повторяющиеся дефисы и обрезать дефис в начале или конце строки. Это мелочь, но именно такие мелочи потом портят адреса страниц.
$code = CUtil::translit($name, 'ru', [
'replace_space' => '-',
'replace_other' => '-',
'change_case' => 'L',
]);
$code = trim(preg_replace('/-+/', '-', $code), '-');
Проверку уникальности лучше делать в том же инфоблоке, где будет создан элемент. Если сайт многоязычный или есть разделы с одинаковыми товарами, заранее решите правило: уникальность на весь инфоблок или только внутри раздела. Для SEO обычно проще и надёжнее уникальность на весь инфоблок.
В итоге функция должна не просто транслитерировать строку, а возвращать готовый символьный код: чистый, нижнего регистра, без мусора и без совпадений с уже существующими элементами.
Механизм без лишних обещаний
Транслитератор решает только преобразование символов. Он не знает инфоблок, язык витрины и уже занятые адреса. Поэтому CODE нужно считать частью данных элемента, а не производным текстовым украшением.
Уникальность проверяется в том же контексте, где код будет использоваться. Для каталога это обычно инфоблок и, возможно, раздел. Если URL глобальный, суффикс нужно добавлять до записи, а не после ошибки маршрута.
Смена CODE — изменение публичного адреса. Нужны редирект или таблица старых ссылок, а также проверка всех мест, где код сохранён как внешний идентификатор.
Минимальный воспроизводимый пример
Ниже — маленькая проверка, которую можно запустить или адаптировать в отдельном тестовом окружении. Значения демонстрационные; проектные идентификаторы, пути и версии нужно заменить своими и сохранить рядом с результатом.
function makeElementCode(string $name, int $id = 0): string
{
$base = CUtil::translit($name, "ru", [
"max_len" => 80,
"change_case" => "L",
"replace_space" => "-",
"replace_other" => "-",
"delete_repeat_replace" => true,
]);
$base = trim(preg_replace("/-+", "-", $base), "-");
$code = $base ?: "item";
$suffix = 1;
while (codeExists($code, $id)) {
$suffix++;
$code = $base . "-" . $suffix;
}
return $code;
}
Матрица диагностики
| Шаг | Вход | Результат |
|---|---|---|
| Транслитерация | Название на русском | Кандидат CODE |
| Нормализация | Пробелы и повторные дефисы | Одна каноническая строка |
| Уникальность | Кандидат и ID текущего элемента | Свободный код или суффикс |
| Публикация | Старый и новый URL | Правило редиректа или ссылки |
Порядок действий
- Выбрать область уникальности: весь инфоблок, раздел или отдельная витрина.
- Сгенерировать кандидат через `CUtil::translit` и нормализовать дефисы.
- Проверить существующий CODE, исключив текущий ID при редактировании.
- Сохранить код только после успешной проверки обязательных данных.
- Для опубликованного элемента сохранить старый URL и проверить переход.
- Добавить тесты для пустого имени, Unicode, повторов и одинаковых названий.
Ограничения и безопасный следующий шаг
Правило транслитерации и параметры `CUtil` зависят от версии Bitrix.
Уникальность в базе должна быть защищена от гонки при параллельном создании.
Суффикс исправляет конфликт, но не решает вопрос понятного URL для бизнеса.
После проверки должен остаться конкретный артефакт: вывод команды, тест, diff конфигурации или запись результата. Если его нет, формулировку нужно вернуть к симптому и не выдавать гипотезу за исправление.
Что записать в ревью
Короткая запись должна отвечать на четыре вопроса: какой вход использовали, какой результат увидели, какая граница была проверена и какое действие разрешено дальше. Такая форма полезнее длинного вывода «всё работает»: другой инженер сможет повторить проверку и понять, где заканчивается пример.
Если результат зависит от версии Windows, PHP, Bitrix, D или браузера, версию фиксируем рядом с командой. Если проверка не охватывает сеть, production или реальные пользовательские данные, это ограничение пишем прямо. Тогда следующий шаг расширяет evidence, а не расширяет обещание.
Проверяемые источники
- Bitrix: CUtil::translit — описывает параметры транслитерации
- Bitrix: CIBlockElement — показывает контекст записи элемента
- Bitrix: URL rewrite — помогает проверить последствия смены адреса