Как я пишу свои компоненты в 1С-Битрикс, чтобы потом не было стыдно
В Bitrix очень легко всё свалить в шаблон готового компонента: немного SQL, пара IncludeComponent, логика фильтров, форматирование цен. Работает — и ладно. Через год к этому страшно прикасаться. Я стараюсь на живых проектах постепенно переходить к своим компонентам и держать в них порядок.
Когда вообще нужен свой компонент
Я не пишу кастомный компонент ради галочки. Он оправдан, когда:
- блок постоянно переиспользуется на разных страницах;
- логика сложнее, чем «просто вывести список элементов»;
- в шаблоне типового компонента уже живут условия, запросы, свои кеши;
- этот блок бизнес будет дорабатывать и расширять.
Если понимаю, что это «кусок функционала», а не просто верстка, — это кандидат под отдельный компонент.
Как я раскладываю структуру компонента
Базовая схема такая:
/bitrix/components/vendor/ my.list/ .description.php class.php templates/ .default/ template.php result_modifier.php style.css
Важные файлы:
- .description.php — регистрация компонента, имя, категории.
- class.php — вся логика: параметры, выборка данных, кеш.
- template.php — только верстка, минимум условий.
- result_modifier.php — подготовка $arResult для шаблона.
Так у меня есть чёткая граница: бизнес-логика и запросы живут в классе, шаблон только показывает.
Что происходит в class.php Я опираюсь на наследника CBitrixComponent и раскладываю код по методам:
- onPrepareComponentParams — приведение и дефолты параметров.
- executeComponent — точка входа, проверка кеша, вызов выборки.
- свои методы loadData(), prepareFilter(), getItems() и т.п.
Минимальный пример:
class VendorMyListComponent extends CBitrixComponent { protected function getItems(): array { $result = [];
$res = CIBlockElement::GetList( ['SORT' => 'ASC'], ['IBLOCK_ID' => $this->arParams['IBLOCK_ID'], 'ACTIVE' => 'Y'], false, ['nTopCount' => (int)$this->arParams['LIMIT']], ['ID','NAME','DETAIL_PAGE_URL'] );
while ($row = $res->GetNext()) { $result[] = $row; }
return $result; }
public function executeComponent() { if ($this->StartResultCache()) { $this->arResult['ITEMS'] = $this->getItems(); $this->IncludeComponentTemplate(); } } }
В шаблон уходит уже готовый массив, без лишних запросов.
Что я делаю в шаблоне В template.php стараюсь не писать ничего, что влияет на бизнес-логику. Там только:
- перебор $arResult['ITEMS'];
- верстка карточек;
- лёгкое форматирование, которое не влияет на данные.
Если нужно подготовить картинку, цену, дату — предпочитаю сделать это в result_modifier.php, чтобы шаблон был максимально плоским и читабельным.
Пара типичных ошибок, которых я избегаю Первая — тащить в свой компонент всё подряд. Компонент должен решать одну задачу: список товаров с особыми условиями, блок отзывов, виджет «вы смотрели». Как только он превращается в универсальный комбайн с десятком режимов, его становится так же больно поддерживать, как и «нагнутый» стандартный.
Вторая — забывать про кеш. Если в компоненте есть серьёзные запросы к БД, я обязательно завожу кеш по ключевым параметрам (IBLOCK_ID, фильтр, кол-во элементов) и не лезу в базу каждый раз. В Bitrix это делается прямо в executeComponent через StartResultCache() и AbortResultCache().
Итог Свой компонент в Bitrix — это способ вынести сложный блок из шаблона в отдельную, предсказуемую сущность. Как только ты разделяешь логику и верстку, аккуратно работаешь с кешем и не превращаешь компонент в свалку всех режимов, поддерживать проект становится проще: можно спокойно дорабатывать функционал, не боясь, что одно правка в шаблоне поломает пять других страниц.