Кастомизация компонента Битрикс: куда копировать шаблон
Правка template.php прямо в /bitrix/components живёт до первого обновления ядра. Разбираем четыре уровня кастомизации — от копии шаблона в /local до наследования класса компонента — и цену каждого.

Задача простая: у bitrix:news.list нужно поменять формат даты, добавить бейдж «новое» и убрать лишний div. Самый быстрый путь — открыть /bitrix/components/bitrix/news.list/templates/.default/template.php и поправить на месте. Работает до первого обновления главного модуля: файл перетирается дистрибутивом, вёрстка на половине сайта разъезжается, а понять причину по логам нельзя — в системе ничего не упало. Второй по популярности путь, кнопка «Копировать шаблон» в публичной панели, спасает от перетирания, но кладёт файлы туда, где их потом никто не ищет. Ниже — четыре уровня вмешательства и цена каждого. Всё относится к 1С-Битрикс: Управление сайтом с ядром main 23.x и новее; папка /local/ появилась ещё в 14-х версиях главного модуля, так что на любой современной сборке она доступна.
Почему оригинал нельзя трогать
Папка /bitrix/ принадлежит дистрибутиву. Обновление модулей распаковывает в неё новые версии файлов и не спрашивает, меняли вы их или нет. Это касается и системных компонентов в /bitrix/components/bitrix/, и шаблонов в /bitrix/templates/.default/. Своя папка вида /bitrix/templates/my_site/ обычно выживает, но держать там правки всё равно не стоит: вы теряете границу между чужим кодом и своим, и при разборе инцидента никто не скажет, какие файлы можно смело вернуть к оригиналу.
/local/ эту границу задаёт физически. Всё, что лежит в ней, — ваше, обновление её не трогает, и в git уходит одна папка вместо выборочных файлов из дистрибутива.
Порядок, в котором Битрикс ищет шаблон
Для вызова $APPLICATION->IncludeComponent('bitrix:news.list', 'blog-list', [...]) ядро перебирает пути и останавливается на первом совпадении:
/local/templates/{текущий_шаблон_сайта}/components/bitrix/news.list/blog-list//local/templates/.default/components/bitrix/news.list/blog-list//bitrix/templates/{текущий_шаблон_сайта}/components/bitrix/news.list/blog-list//bitrix/templates/.default/components/bitrix/news.list/blog-list//local/components/bitrix/news.list/templates/blog-list//bitrix/components/bitrix/news.list/templates/blog-list/
Отсюда два практических следствия. Первое: кастомный шаблон достаточно положить в /local/templates/.default/components/... — он подхватится на всех шаблонах сайта. Второе: если на одном шаблоне сайта правки видны, а на другом нет, почти всегда виноват уровень 1, который перекрывает .default. Точный порядок для вашей сборки стоит сверить в документации по шаблонам компонентов, он описан в разделе про Bitrix Framework.
Четыре уровня вмешательства
1. Только шаблон
Копируете папку шаблона из /bitrix/components/bitrix/news.list/templates/.default/ в /local/templates/.default/components/bitrix/news.list/blog-list/ и меняете в вызове имя шаблона на blog-list. Логика компонента остаётся системной и продолжает обновляться. Вместе с template.php в папке живут style.css и script.js — ядро подключает их автоматически, .parameters.php добавляет свои настройки шаблона в визуальный редактор, lang/ru/template.php — языковые фразы.
Цена: вёрстка замерзает. Исправления и новые возможности, которые вендор внесёт в штатный template.php, до вас не дойдут никогда.
2. Шаблон плюс result_modifier.php
Если править нужно данные, а не разметку, не разводите логику по template.php. result_modifier.php выполняется после компонента и до шаблона, в нём доступен и изменяем $arResult:
<?php
// /local/templates/.default/components/bitrix/news.list/blog-list/result_modifier.php
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) {
die();
}
foreach ($arResult['ITEMS'] as $index => $item) {
// Готовим дату заранее, чтобы в template.php не осталось вычислений
$arResult['ITEMS'][$index]['SHORT_DATE'] = FormatDate(
'j F',
MakeTimeStamp($item['ACTIVE_FROM'])
);
$arResult['ITEMS'][$index]['HAS_PREVIEW'] = !empty($item['PREVIEW_TEXT']);
}
// То, что понадобится вне кеша, кладём в arResult самого компонента
$this->__component->arResult['ITEMS_COUNT'] = count($arResult['ITEMS']);
Важный нюанс: result_modifier.php попадает в кеш компонента вместе с результатом. Всё, что должно работать на каждом запросе — заголовок страницы, хлебные крошки, счётчики, — переносите в component_epilog.php, он выполняется и при попадании в кеш:
<?php
// .../news.list/blog-list/component_epilog.php
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) {
die();
}
global $APPLICATION;
$itemsCount = (int)($arResult['ITEMS_COUNT'] ?? 0);
$APPLICATION->SetTitle('Блог: ' . $itemsCount . ' материалов');
В эпилоге виден только тот набор данных, который компонент выгружает из кеша, — поэтому значение и экспортировалось через $this->__component->arResult. Состав доступных переменных в эпилоге сверяйте с документацией по вашей версии ядра: он скромнее, чем в шаблоне.
3. Копия компонента в /local/components
Нужна, когда менять приходится сам запрос: другой набор полей, своя фильтрация, нештатная пагинация. Копируете папку компонента в /local/components/mycompany/news.list/ и меняете вызов на mycompany:news.list. Пространство имён обязательно своё: если оставить bitrix, ваша копия в /local/components/bitrix/ перекроет системный компонент на всём сайте, включая страницы, которые вы не собирались трогать.
Цена высокая. Вы забираете на себя весь component.php или class.php, вместе с исправлениями ошибок и безопасности, которые вендор выпустит позже. Для каталожных компонентов это десятки килобайт чужой логики под вашу ответственность.
4. Наследование класса компонента
Компромисс для компонентов, у которых есть class.php: своя копия содержит только класс-наследник, а тело логики остаётся в дистрибутиве и обновляется. Схематично:
<?php
// /local/components/mycompany/catalog.section/class.php — схематично
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) {
die();
}
CBitrixComponent::includeComponentClass('bitrix:catalog.section');
// Имя родительского класса возьмите из class.php оригинала — оно у каждого компонента своё
class MyCatalogSection extends OriginalComponentClass
{
public function onPrepareComponentParams($arParams)
{
$arParams = parent::onPrepareComponentParams($arParams);
$arParams['PAGE_ELEMENT_COUNT'] = 24; // своё значение по умолчанию
return $arParams;
}
}
Подход живёт ровно до момента, когда вендор переименует метод или изменит его контракт. Поэтому имена переопределяемых методов проверяйте по исходнику той версии, которая стоит у вас, а не по статьям в интернете.
Сравнение подходов
| Подход | Что меняете | Куда кладёте | Что приносят обновления | Цена |
|---|---|---|---|---|
| Правка оригинала | что угодно | /bitrix/components/bitrix/ | перетирают правки | потеря работы без предупреждения |
| Копия шаблона | разметку, CSS, JS | /local/templates/.default/components/ | логику обновляют, шаблон нет | чужие правки вёрстки мимо вас |
| Шаблон + result_modifier | подготовку данных для вывода | та же папка шаблона | логику обновляют | нужно помнить про кеш и эпилог |
| Копия компонента | запрос, параметры, логику | /local/components/{вендор}/ | ничего | вся логика и её багфиксы на вас |
| Наследование класса | отдельные методы | /local/components/{вендор}/ | обновляют родительский класс | ломается при смене контракта методов |
Чем ниже уровень вмешательства, тем дешевле обновление. Копия шаблона стоит вам чужих правок вёрстки, копия компонента — чужих правок логики, включая исправления безопасности.
Когда что выбирать
- Меняется только то, что видно в браузере — копия шаблона. Девяносто процентов задач по кастомизации заканчиваются здесь.
- Данные есть в
$arResult, но не в том виде —result_modifier.php. Если значения в$arResultнет вообще, смотрите параметры компонента, а не копирование: у штатных компонентов есть параметры для дополнительных свойств инфоблока. - Нужно другое выборкой из базы — сначала проверьте события модуля инфоблоков в
/local/php_interface/init.php. Копия компонента — следующий шаг, когда событий не хватает. - Нужен один-два метода — наследование, и только если у компонента есть
class.php.
Что ломается чаще всего
- Правки не видны на части страниц. Шаблон лежит в
.default, а на этих страницах активен шаблон сайта со своей копией компонента — уровень 1 перекрывает уровень 2. - Правки не видны вообще. Отдаётся кеш компонента или композитный HTML. Очистите файлы кеша в настройках главного модуля и проверьте в приватном окне.
- Заголовок страницы меняется через раз.
SetTitleвызывается изtemplate.phpилиresult_modifier.phpи работает только на промахе кеша. Переносите вcomponent_epilog.php. - Белый экран после копирования. Чаще всего это права и владелец файлов: веб-сервер не читает папку, созданную от другого пользователя. Смотрите не в логи Битрикса, а в error_log PHP.
- Кнопка «Копировать шаблон» положила файлы не туда. Она копирует в папку активного шаблона сайта, то есть в
/bitrix/templates/..., если шаблон сайта живёт там. Переносите в/local/вручную. - Своя копия компонента в
/local/components/bitrix/. Перекрывает системный компонент глобально — ломается там, где никто не ждал.
result_modifier.php — необязательный файл в папке шаблона компонента. Если он есть, ядро подключает его между работой компонента и выводом шаблона, давая изменить массив результата $arResult. component_epilog.php — такой же необязательный файл, но выполняется после шаблона и вне кеша компонента.
Что делать дальше
Поставьте /local/ под git отдельной папкой и исключите из репозитория /bitrix/ — тогда следующее обновление ядра не будет выглядеть как тысяча изменённых файлов. Перед обновлением прогоняйте его на копии и проверяйте страницы с кастомными шаблонами: именно они дают визуальные регрессии, которые не видны в логах. Если скопированных шаблонов уже больше десятка, завидите список вызовов с нештатными шаблонами — пригодится при любом разборе. Инвалидация кеша и настройка композита — отдельные темы, здесь мы разобрали только размещение файлов.
Репетитор 1—11 класс и ВУЗ: Математика и физика методом наведения на мысль, помощь с ДЗ.
Спросить за 8 ₽Источники: 1С-Битрикс: документация для разработчиков (Bitrix Framework), разделы о компонентах и их шаблонах, 1С-Битрикс: учебный курс «Разработчик Bitrix Framework» — кастомизация компонентов и папка /local/
Частые вопросы
Кнопка «Копировать шаблон» в публичной панели кладёт файлы куда надо?
Нужно ли копировать компонент целиком, если надо изменить только запрос к инфоблоку?
У меня старое ядро, папки /local/ на сайте нет. Что делать?
Скопировал шаблон, поменял имя в вызове, а сайт показывает старый вывод. Где искать?
Что проверять в проде после кастомизации?
Правки в /bitrix/components точно сотрутся или только иногда?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.