Компоненты в Битрикс: разбор на примере
Разбираем компонент 1С-Битрикс на небольшом примере со списком элементов инфоблока: из каких файлов он состоит, где выполнять запрос к данным и почему код в шаблоне быстро превращается в проблему.

В 1С-Битрикс один и тот же список новостей можно вывести за несколько минут, но поддерживать такой код годами получится только при правильном разделении ответственности. В этом разборе соберём собственный компонент acme:news.list для версий 1С-Битрикс: Управление сайтом 24.x–25.x, разложим его по файлам и сравним с запросом прямо из шаблона.
Что именно делает компонент
Компонент принимает идентификатор инфоблока и количество элементов, получает активные записи, передаёт их в шаблон и не смешивает выборку данных с HTML-разметкой.
Для примера возьмём список новостей. В реальном проекте вместо него может быть каталог товаров, блок акций или подборка материалов. Принцип тот же: компонент готовит результат, шаблон отвечает за внешний вид.
Хороший компонент можно заменить другим шаблоном, не переписывая запрос к базе, и изменить источник данных, не редактируя HTML.
Из каких частей он состоит
.description.php— название и описание компонента в визуальном редакторе;.parameters.php— параметры, которые администратор или разработчик задаёт при подключении;component.php— получение и подготовка данных;template.php— разметка результата;result_modifier.php— дополнительная подготовка результата перед шаблоном, если она действительно нужна;component_epilog.php— действия после выполнения шаблона, например подключение отложенных операций.
Для первого компонента достаточно четырёх файлов: описания, параметров, основной логики и шаблона.
Инфоблок — сущность 1С-Битрикс для хранения однотипных элементов и их свойств: новостей, товаров, статей или разделов каталога.
Где хранить компонент
Пользовательские компоненты размещайте в /local/components/, а не в /bitrix/components/. Каталог ядра обновляется вместе с системой, поэтому изменения внутри него легко потерять.
Для примера структура будет такой:
/local/components/acme/news.list/
├── .description.php
├── .parameters.php
├── component.php
└── templates/
└── .default/
└── template.php
Пара acme:news.list состоит из пространства имён acme и имени компонента news.list. Пространство имён помогает не столкнуть собственный компонент с одноимённым решением из Marketplace или ядра.
Компонент на примере списка новостей
1. Описание
Файл .description.php нужен для списка компонентов и визуального редактора. Он не получает данные и не участвует в выводе страницы.
<?php
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) {
die();
}
$arComponentDescription = [
'NAME' => 'Список новостей',
'DESCRIPTION' => 'Выводит активные элементы инфоблока',
'PATH' => [
'ID' => 'acme',
'NAME' => 'Собственные компоненты',
],
];
Проверка простая: после очистки кеша компонент должен появиться в группе «Собственные компоненты».
2. Параметры
В .parameters.php объявим идентификатор инфоблока и число элементов. Значение IBLOCK_ID не стоит зашивать в component.php: на другой странице понадобится другой инфоблок.
<?php
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) {
die();
}
$arComponentParameters = [
'GROUPS' => [],
'PARAMETERS' => [
'IBLOCK_ID' => [
'PARENT' => 'BASE',
'NAME' => 'ID инфоблока',
'TYPE' => 'STRING',
'DEFAULT' => '',
],
'COUNT' => [
'PARENT' => 'BASE',
'NAME' => 'Количество элементов',
'TYPE' => 'STRING',
'DEFAULT' => '5',
],
'CACHE_TIME' => [
'DEFAULT' => 3600,
],
],
];
Проверка: при добавлении компонента в визуальном редакторе должны появиться поля «ID инфоблока» и «Количество элементов».
3. Получение данных
Запрос выполняется в component.php. Здесь мы подключаем модуль информационных блоков, проверяем параметры, используем кеш компонента и передаём в шаблон только нужные поля.
<?php
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) {
die();
}
use Bitrix\Main\Loader;
if (!Loader::includeModule('iblock')) {
ShowError('Не удалось подключить модуль информационных блоков');
return;
}
$iblockId = (int)$arParams['IBLOCK_ID'];
$elementCount = max(1, (int)$arParams['COUNT']);
if ($iblockId <= 0) {
ShowError('Не указан инфоблок');
return;
}
if ($this->startResultCache(false, [$iblockId, $elementCount])) {
$arResult = [
'ITEMS' => [],
];
$elements = CIBlockElement::GetList(
[
'SORT' => 'ASC',
'ACTIVE_FROM' => 'DESC',
],
[
'IBLOCK_ID' => $iblockId,
'ACTIVE' => 'Y',
],
false,
[
'nTopCount' => $elementCount,
],
[
'ID',
'NAME',
'DETAIL_PAGE_URL',
'PREVIEW_TEXT',
]
);
while ($element = $elements->GetNext()) {
$arResult['ITEMS'][] = [
'ID' => (int)$element['ID'],
'NAME' => $element['NAME'],
'URL' => $element['DETAIL_PAGE_URL'],
'PREVIEW_TEXT' => $element['PREVIEW_TEXT'],
];
}
$this->includeComponentTemplate();
}
Проверка: при открытии страницы с компонентом должен появиться список активных элементов. Если инфоблок пуст, шаблон покажет сообщение, которое мы добавим ниже.
В примере используется старый, но поддерживаемый в типовых проектах процедурный API модуля инфоблоков. Если проект уже переводят на ORM, запрос можно заменить на ORM-слой, но это отдельная задача: смешивать оба подхода в одном небольшом компоненте не нужно.
4. Шаблон
Файл templates/.default/template.php получает результат через $arResult. Не помещайте сюда запросы к базе: иначе шаблон перестанет быть только представлением.
<?php
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) {
die();
}
if (empty($arResult['ITEMS'])):
?>
<p>Новостей пока нет.</p>
<?php
return;
endif;
?>
<ul class="news-list">
<?php foreach ($arResult['ITEMS'] as $item): ?>
<li class="news-list__item">
<a href="<?=htmlspecialcharsbx($item['URL'])?>">
<?=htmlspecialcharsbx($item['NAME'])?>
</a>
<?php if ($item['PREVIEW_TEXT'] !== ''): ?>
<p><?= $item['PREVIEW_TEXT'] ?></p>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ul>
Проверка: в HTML должен появиться список ссылок, а в адресах — URL элементов инфоблока. Функция htmlspecialcharsbx защищает атрибут ссылки и заголовок от вывода специальных символов в исходном виде.
Как подключить компонент на странице
Подключение выполняется через стандартный вызов $APPLICATION->IncludeComponent. В шаблоне страницы или в PHP-файле раздела он выглядит так:
<?php
$APPLICATION->IncludeComponent(
'acme:news.list',
'.default',
[
'IBLOCK_ID' => 7,
'COUNT' => 5,
'CACHE_TIME' => 3600,
]
);
Число 7 здесь условное: укажите реальный ID инфоблока вашего проекта. Кеш на 3600 секунд означает, что результат может оставаться неизменным до часа. После публикации новости очищайте кеш компонента или выбирайте стратегию кеширования, подходящую для редакционного процесса.
Компонент или запрос в шаблоне
Оба способа могут вывести список, но цена изменений у них разная.
| Подход | Когда подходит | Цена |
|---|---|---|
| Компонент с отдельным шаблоном | Блок повторяется на нескольких страницах или имеет параметры | Нужно создать структуру файлов и продумать кеш |
| Запрос прямо в шаблоне страницы | Одноразовый прототип или короткая временная страница | Логика и HTML смешиваются, повторное использование становится дорогим |
Если блок должен пережить редизайн, выбирайте компонент. Если это одноразовый технический экран, прямой запрос иногда быстрее, но его стоит считать временным решением и не копировать на соседние страницы.
Что ломается чаще всего
- Белый экран. Обычно PHP-файл содержит синтаксическую ошибку или обращается к несуществующему ключу. Смотрите журнал PHP и включайте режим отладки только на тестовом окружении.
- «Не удалось подключить модуль информационных блоков». Проверьте установку модуля и не подавляйте ошибку оператором подавления.
- Пустой список. Проверьте ID инфоблока, активность элементов, права доступа и кеш. В фильтре примера выбираются только элементы с
ACTIVE = Y. - Старые данные после редактирования. Причина обычно в кеше компонента. Очистите кеш конкретного компонента, а не весь кеш сайта без необходимости.
- HTML ломается в заголовке или ссылке. Экранируйте значение в контексте вывода: отдельно для текста и отдельно для атрибутов.
Где такой компонент перестаёт подходить
Пример рассчитан на простой список элементов. Он не решает постраничную навигацию, фильтрацию по свойствам, сложные права доступа и загрузку связанных сущностей. Добавлять всё это прямо в один файл не стоит: вынесите отдельные требования в параметры или создайте специализированный компонент.
Особенно осторожно работайте с кешем, если результат зависит от пользователя, группы доступа или персональных цен. Общий кеш в такой ситуации может показать одному посетителю данные другого. Схему кеширования нужно проверять отдельно на тестовых аккаунтах.
Что делать дальше
Сначала установите компонент на тестовой странице и проверьте четыре сценария: корректный инфоблок, пустой инфоблок, неверный ID и очищенный кеш. Затем добавьте постраничную навигацию, если список вырастет, и замерьте время ответа страницы до и после включения кеша. После этого вынесите стили в проектную сборку, а не добавляйте их внутрь шаблона компонента.
Тест и проверочная: Быстрые ответы с объяснением, почему остальные варианты неверны
Спросить за 10 ₽Источники: 1С-Битрикс: CMain::IncludeComponent, 1С-Битрикс: документация разработчика
Частые вопросы
Можно ли хранить собственный компонент в /bitrix/components?
Почему компонент не показывает элементы инфоблока?
Нужно ли использовать result_modifier.php для подготовки данных?
Что делать, если после изменения новости на странице остаются старые данные?
Совместим ли пример с любой версией Битрикс?
Можно ли заменить запрос CIBlockElement на ORM?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.