СезонГотовим магазин к высокому сезону и Чёрной пятнице: скорость, нагрузка, акции

Шаблоны и компоненты 1С-Битрикс: как устроен фронтенд магазина

Шаблоны и компоненты 1С-Битрикс: устройство фронтенда магазина, шаблон сайта, компоненты и их шаблоны, кастомизация

Новый разработчик открывает проект на 1С-Битрикс, видит папки bitrix, local, upload и десятки вызовов IncludeComponent — и не понимает, где вообще «лежит вёрстка». Где менять шапку? Почему правка списка товаров в одной папке ничего не даёт, а в другой всё ломает при обновлении? Ответ в том, что фронтенд Битрикса устроен слоями: есть шаблон сайта, есть компоненты, а у каждого компонента — свои шаблоны. Пока эта картина не уложилась в голове, любая правка похожа на гадание.

Эта статья — карта фронтенда магазина на Битриксе для тех, кто хочет уверенно менять вёрстку, а не бояться её. Разберём, как связаны шаблон сайта и компоненты, чем комплексный компонент (например, bitrix:catalog) отличается от простого, из каких файлов состоит компонент и его шаблон (component.php, template.php, result_modifier.php, component_epilog.php), как правильно кастомизировать вёрстку копированием в свой namespace без правки ядра, и как всё это дружит с кэшем и композитом. Материал — выжимка из наших проектов по разработке интернет-магазинов на 1С-Битрикс.

Коротко

  • Фронтенд Битрикса — три уровня: шаблон сайта (шапка/подвал), компоненты (блоки с логикой) и шаблоны компонентов (их вёрстка).
  • Простой компонент выводит один блок; комплексный (как bitrix:catalog) управляет несколькими страницами по ЧПУ и вызывает простые внутри себя.
  • Шаблон компонента — это template.php плюс result_modifier.php, component_epilog.php, style.css, script.js и lang.
  • Кастомизация — копированием шаблона в свой шаблон сайта; править bitrix/ нельзя — перезапишется при обновлении.
  • Данные шаблон получает в $arResult, настройки — в $arParams; тяжёлую доводку данных держат в result_modifier, некэшируемое — в эпилоге.

Зачем разработчику понимать устройство фронтенда

1С-Битрикс часто ругают за «магию»: страница будто собирается сама, а где именно менять разметку — неочевидно. На деле никакой магии нет, есть чёткая архитектура. Как только становится понятно, какой уровень за что отвечает, правки перестают быть лотереей: вы точно знаете, в каком файле поменять шапку, в каком — вёрстку карточки товара, а в каком — логику получения данных. Это экономит часы и, что важнее, спасает от правок, которые сломаются при первом же обновлении платформы.

Понимание устройства фронтенда даёт три практических выигрыша:

Обратная сторона незнания — типичная боль запущенных проектов: правки внутри bitrix/, которые исчезают после апдейта; логика, зашитая прямо в HTML; компоненты с отключённым кэшем «на время отладки», забытые в продакшене. Всё это лечится одним — пониманием слоёв фронтенда, к которому мы и переходим.

Три уровня фронтенда: сайт, компоненты, их шаблоны

Первое, что нужно уложить в голове, — фронтенд Битрикса собирается из трёх вложенных уровней. Они не конкурируют, а вкладываются друг в друга, как матрёшка: шаблон сайта задаёт рамку, внутри рамки работают компоненты, а каждый компонент рисуется своим шаблоном.

Ключевая мысль: страница в Битриксе — это шаблон сайта, в рабочую область которого вставлены вызовы компонентов, а каждый компонент отрисован своим шаблоном. Когда вы понимаете, на каком уровне находится нужная правка, вопрос «где менять» отпадает сам собой. Дальше разберём каждый уровень по отдельности, начиная с внешней рамки — шаблона сайта.

Страница = шаблон сайта + компоненты в рабочей области Шапка (header.php): логотип, меню, корзина Рабочая область страницы bitrix:menu компонент меню bitrix:breadcrumb хлебные крошки bitrix:catalog комплексный компонент каталога список / карточка товара Подвал (footer.php): контакты, меню, счётчики шаблон сайта оборачивает всё
Схема: шаблон сайта задаёт шапку и подвал, а в рабочую область вставлены вызовы компонентов — простых (меню, крошки) и комплексных (каталог).

Шаблон сайта: header, footer и рабочая область

Шаблон сайта — это внешняя «рамка» всех страниц. Технически он представлен двумя главными файлами: header.php и footer.php. Всё, что идёт до тела страницы (открытие HTML, <head>, шапка, открывающие теги контейнеров), лежит в header.php; всё, что после (подвал, закрывающие теги, счётчики), — в footer.php. А между ними платформа подставляет содержимое конкретной страницы — так называемую рабочую область.

Механика проще, чем кажется. Любая публичная страница Битрикса начинается с подключения пролога и заканчивается подключением эпилога:

<?php
require($_SERVER['DOCUMENT_ROOT'].'/bitrix/header.php');
// ↑ этот вызов подтягивает header.php вашего шаблона сайта

$APPLICATION->SetTitle('Каталог');
// ... здесь тело страницы: текст, вызовы компонентов ...

require($_SERVER['DOCUMENT_ROOT'].'/bitrix/footer.php');
// ↓ этот вызов подтягивает footer.php вашего шаблона сайта

Между header.php и footer.php и находится рабочая область — всё, что вы пишете в самом файле страницы. Именно сюда попадают вызовы компонентов. Такая схема даёт единообразие: поменяли шапку в одном header.php — она изменилась на всех страницах разом, потому что все они оборачиваются одним и тем же шаблоном сайта.

Внутри header.php живёт ключевая для вёрстки конструкция — вывод «дельты» страницы. Метод $APPLICATION->ShowHead() выводит собранные стили и скрипты, а служебная область до и после рабочей зоны отвечает за навигацию, панель и прочую обвязку. Разработчику важно помнить: заголовок страницы (SetTitle), мета-теги и хлебные крошки формируются в теле страницы или в эпилогах компонентов, а выводятся в шапке — поэтому порядок подключения имеет значение.

Что лежит в папке шаблона сайта

Каждый шаблон сайта — это папка внутри bitrix/templates/ (или в local/templates/ при использовании папки local). Её содержимое стандартизировано, и знание этого набора экономит массу времени при разборе чужого проекта.

Файл / папкаЧто делает
header.phpВерх страницы: <head>, шапка, открытие контейнеров, вывод стилей/скриптов
footer.phpНиз страницы: подвал, закрытие контейнеров, счётчики
styles.css / template_styles.cssСтили шаблона сайта и стили редактируемых областей
.style.phpОписание типовых блоков для визуального редактора
components/Переопределённые (скопированные) шаблоны компонентов — сюда кладут кастомизацию
page_templates/Шаблоны новых страниц (готовые «рыбы» разделов)
include_areas/Включаемые области: редактируемые куски (телефон, акции, тексты)
lang/Языковые сообщения шаблона сайта
images/, fonts/Статические ресурсы темы оформления

Особого внимания заслуживает папка components/ внутри шаблона сайта. Это «место силы» кастомизации: сюда кладут переопределённые шаблоны компонентов, и именно отсюда платформа берёт вёрстку в первую очередь. Мы вернёмся к этому в разделе про кастомизацию — там станет понятно, почему копировать шаблон нужно именно в bitrix/templates/ваш_шаблон/components/, а не куда-то ещё.

Папка local. В современных проектах кастомный код и шаблоны выносят в отдельную папку /local/ (там свои templates/ и components/). Это ещё чётче отделяет ваш код от ядра: всё «своё» лежит в local, всё «системное» — в bitrix. Логика приоритетов при этом та же: платформа сначала ищет ваши шаблоны, потом штатные.

Что такое компонент и что он инкапсулирует

Компонент — центральное понятие фронтенда Битрикса. Это самодостаточный блок, который умеет две вещи: получить данные (например, выбрать товары раздела из инфоблока) и отдать их шаблону для вывода. Всё, что между — какие запросы к базе, как обрабатываются права, как строится кэш, — спрятано внутри компонента. Разработчику страницы достаточно вызвать компонент и передать параметры, а «как оно работает» его не касается.

Именно эта инкапсуляция и есть главная ценность компонентной модели. Список товаров, меню, форма обратной связи, регистрация, корзина — всё это готовые компоненты, которые можно поставить на страницу одним вызовом. Внутри они решают сложные задачи (выборки, пагинация, кэш, безопасность), но наружу выставляют простой контракт: набор параметров на входе и HTML на выходе.

Технически у компонента есть строгая логика разделения: логика (получение данных) отделена от представления (вывод). Логика живёт в основном файле компонента и формирует массив данных $arResult; представление живёт в шаблоне компонента и этот массив выводит. Благодаря такому разделению один и тот же компонент можно отрисовать десятком разных шаблонов, ничего не меняя в его логике, — и наоборот, поменять источник данных, не трогая вёрстку.

Ключевая идея: компонент = «логика + контракт данных», шаблон компонента = «как это выглядит». Меняя вёрстку блока, вы работаете с шаблоном компонента и почти никогда — с самим компонентом. Меняя источник или логику данных, работаете с компонентом. Это разделение — фундамент всей кастомизации.

Простые и комплексные компоненты

Все компоненты делятся на два класса, и разница между ними определяет, как вы будете с ними работать. Простой компонент выводит один блок и живёт на одной странице. Комплексный компонент управляет сразу несколькими логическими страницами и внутри себя вызывает простые компоненты.

Простой компонент — это, например, bitrix:menu (меню), bitrix:breadcrumb (хлебные крошки), bitrix:catalog.section (список товаров одного раздела) или bitrix:catalog.element (одна карточка товара). Каждый из них делает ровно одну вещь и выводит ровно один блок. Ставите такой компонент на страницу — получаете этот блок, и всё.

Комплексный компонент — это «страничный менеджер». Он умеет по адресу (ЧПУ) понять, какую именно страницу от него хотят, и подключить нужный простой компонент. Самый известный пример — bitrix:catalog: он сам разбирает URL и решает, что показать — список разделов, список товаров раздела или карточку товара, — и подключает соответственно catalog.section.list, catalog.section или catalog.element. Поэтому у комплексного компонента есть настройки ЧПУ (SEF) и целый набор шаблонов под разные страницы.

ПризнакПростой компонентКомплексный компонент
Сколько страниц обслуживаетОдну (один блок)Несколько логических страниц
Разбор ЧПУ (SEF)НетДа, свой роутинг по URL
Вложенные компонентыНетВнутри вызывает простые
Примерbitrix:menu, bitrix:catalog.elementbitrix:catalog, bitrix:news
Шаблонов у компонентаОдин основнойСвой на каждую страницу + вложенных

Практический вывод: если вам нужен один блок на конкретной странице (список товаров в разделе, который вы сверстали сами), берёте простой компонент. Если нужен «каталог целиком» с разделами, товарами, карточками и ЧПУ из коробки — берёте комплексный. Кастомизация у них устроена похоже, но у комплексного шаблонов больше, потому что каждой внутренней странице соответствует свой.

Комплексный компонент управляет страницами по ЧПУ bitrix:catalog разбирает URL (SEF) catalog.section.list список разделов /catalog/ catalog.section список товаров /catalog/shoes/ catalog.element карточка товара /catalog/shoes/nike/
Схема: комплексный компонент каталога по адресу определяет нужную страницу и подключает соответствующий простой компонент — список разделов, список товаров или карточку.

bitrix:catalog как комплексный компонент

Разберём bitrix:catalog подробнее, потому что это самый частый комплексный компонент в магазине и на нём хорошо видно всю механику. Когда вы ставите его на страницу /catalog/ и включаете режим ЧПУ, он берёт на себя весь каталог: от списка разделов до карточки конкретного товара. Одна точка входа — десятки страниц.

Работает это так. Компонент получает «хвост» URL после /catalog/ и сверяет его с шаблонами путей из своих настроек SEF: пусто — показать корень каталога, один сегмент — раздел, сегмент плюс код элемента — карточку. Определив тип страницы, он подключает нужный вложенный простой компонент и передаёт ему разобранные параметры (код раздела, код элемента, номер страницы пагинации). Дальше уже простой компонент выбирает данные и отрисовывает свой шаблон.

Отсюда важное следствие для кастомизации. У комплексного bitrix:catalog есть свой набор шаблонов — на список разделов, на список товаров, на карточку и так далее. Когда вы копируете шаблон комплексного компонента, вы получаете все эти файлы сразу и правите нужный. При этом вложенные простые компоненты тоже имеют свои шаблоны, и иногда кастомизировать нужно именно их — об этом отдельный раздел ниже.

Ещё один нюанс — производительность. Комплексный компонент удобен, но «тяжёл»: он тянет за собой всю инфраструктуру каталога. Для витрины это оправдано, но если на странице нужен один маленький блок «хиты продаж», комплексный компонент туда ставить не стоит — берут простой catalog.section с нужной выборкой. Как вся эта конструкция кэшируется и почему это критично для скорости, мы подробно разбираем в материале про кэширование в 1С-Битрикс.

Структура компонента: component.php и файлы

Заглянем внутрь компонента. Любой компонент — это папка со стандартным набором файлов, и структура эта одинакова для штатных и кастомных. Понимание, за что отвечает каждый файл, — половина успеха при отладке и разработке.

ФайлРоль
component.phpГлавный файл: получает данные, формирует $arResult, подключает шаблон
class.phpКласс компонента (современный стиль): логика в методах вместо процедурного component.php
.parameters.phpОписание входных параметров компонента для формы настроек
.description.phpИмя, описание и место компонента в дереве выбора
templates/Папка со всеми шаблонами компонента (.default и другие)
lang/Языковые сообщения самого компонента

Сердце компонента — component.php (или метод executeComponent() в class.php). Именно он получает параметры, обращается к базе, формирует массив результата и запускает вывод шаблона. Схематично простой компонент выглядит так:

<?php
// component.php — упрощённо
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) die();

// 1. Кэш: если валиден — данные восстановятся сами
if ($this->startResultCache()) {

    // 2. Получение данных → формируем $arResult
    $arResult['ITEMS'] = getSomeItems($arParams['IBLOCK_ID']);

    // 3. Регистрируем тег для автосброса кэша
    global $CACHE_MANAGER;
    $CACHE_MANAGER->RegisterTag('iblock_id_' . $arParams['IBLOCK_ID']);

    // 4. Подключаем шаблон (он увидит $arResult и $arParams)
    $this->includeComponentTemplate();
}

Обратите внимание: сам component.php не содержит ни строчки HTML. Он только готовит $arResult и вызывает includeComponentTemplate(), который и подключает шаблон. Это и есть разделение логики и представления в действии. Файлы .parameters.php и .description.php — служебные: первый описывает, какие настройки покажутся в форме компонента, второй — как компонент называется и где лежит в дереве выбора. При кастомизации вёрстки их обычно не трогают вовсе.

Внутренний конвейер компонента component.php логика, выборки → $arResult result_modifier доводка данных (в кэше) template.php вывод HTML (в кэше) epilog после кэша, каждый запрос Граница кэша компонента modifier и template кэшируются, epilog — нет
Схема: данные проходят через component.php → result_modifier → template.php; result_modifier и template попадают в кэш, а эпилог выполняется вне кэша на каждый запрос.

Шаблон компонента: template.php и окружение

Теперь спускаемся на самый интересный для вёрстки уровень — шаблон компонента. Он живёт в папке templates/имя_шаблона/ внутри компонента. Шаблон по умолчанию называется .default; кроме него у компонента может быть сколько угодно именованных шаблонов (list, slider, bootstrap_v4 и т. д.), и нужный выбирается параметром при вызове компонента.

Главный файл шаблона — template.php. Именно он превращает массив $arResult в HTML. Внутри ему доступны несколько «магических» переменных, которые платформа готовит автоматически:

ПеременнаяЧто содержит
$arResultДанные, подготовленные компонентом (товары, свойства, цены)
$arParamsПараметры, с которыми вызван компонент
$APPLICATIONОбъект приложения (заголовок, крошки, ресурсы)
$component / $thisСам компонент и его методы (для шаблона)
$templateFolderПуть к папке шаблона (для ссылок на картинки)

Типичный template.php списка товаров — это цикл по $arResult['ITEMS'] с аккуратным экранированием вывода:

<?php if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) die(); ?>

<div class="product-list">
  <?php foreach ($arResult['ITEMS'] as $item): ?>
    <div class="product-card">
      <a href="<?= $item['DETAIL_PAGE_URL'] ?>">
        <img src="<?= $item['PREVIEW_PICTURE']['SRC'] ?>" alt="<?= htmlspecialcharsbx($item['NAME']) ?>">
        <span class="name"><?= htmlspecialcharsbx($item['NAME']) ?></span>
      </a>
      <span class="price"><?= $item['PRICE_FORMATTED'] ?></span>
    </div>
  <?php endforeach; ?>
</div>

Обратите внимание на htmlspecialcharsbx() — это штатная функция Битрикса для безопасного вывода. Любые данные, идущие в HTML, нужно экранировать, иначе получите XSS или сломанную вёрстку. Заметьте и то, что в шаблоне нет запросов к базе и тяжёлой логики: только вывод готовых данных. Если в template.php появляются выборки из инфоблоков в цикле — это сигнал, что логику пора вынести в component.php или в result_modifier.php.

result_modifier.php: доводка $arResult

Рядом с template.php может лежать файл result_modifier.php — один из самых полезных и недооценённых инструментов кастомизации. Он выполняется до template.php и предназначен для того, чтобы дополнить или преобразовать массив $arResult перед выводом. Это «прослойка данных» между логикой компонента и вёрсткой.

Зачем он нужен, если данные уже подготовил компонент? Затем, что часто нужно что-то доработать, не влезая в саму логику компонента: добавить вычисляемое поле, отформатировать цену, подтянуть связанные данные, перегруппировать элементы. Делать это прямо в template.php — плохо: вёрстка засоряется логикой. Делать в component.php — нельзя, если это штатный компонент (это правка ядра). Решение — result_modifier.php: он часть шаблона, а значит ваш, но при этом отделён от вёрстки.

<?php
// result_modifier.php — выполняется до template.php
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) die();

foreach ($arResult['ITEMS'] as &$item) {
    // Добавляем вычисляемый флаг «новинка»
    $item['IS_NEW'] = !empty($item['PROPERTIES']['NEW']['VALUE']);

    // Готовим короткий анонс для карточки
    $item['SHORT_TEXT'] = mb_substr(strip_tags($item['PREVIEW_TEXT']), 0, 120);
}
unset($item);

Ключевое преимущество — result_modifier попадает в кэш компонента. Он выполняется внутри границы кэша, значит его тяжёлая работа (форматирование, доп. выборки) считается один раз при сборке кэша, а не на каждый запрос. Поэтому именно сюда правильно выносить любую «доводку данных»: это и чисто (вёрстка остаётся вёрсткой), и быстро (результат кэшируется).

Практика: если тянет дописать foreach с логикой прямо в template.php — остановитесь и перенесите это в result_modifier.php. Шаблон должен читаться как HTML с минимальными вставками вывода, а вся подготовка данных — жить в модификаторе. Это резко упрощает поддержку.

component_epilog.php: код после кэша

Есть задачи, которые нельзя кэшировать: они должны выполняться на каждый запрос, даже когда основная часть компонента отдана из кэша. Для них существует component_epilog.php — файл шаблона, который платформа выполняет всегда, вне кэша, после того как компонент завершил работу.

Почему это важно? Представьте, что вы в template.php ставите заголовок страницы через $APPLICATION->SetTitle(). Пока кэш пуст, всё работает: шаблон выполняется, заголовок ставится. Но как только компонент попадёт в кэш, template.php больше не выполнится (его результат берётся из кэша) — и заголовок «залипнет» на том, что был. Классический баг: у всех страниц каталога один и тот же title. Лечится переносом установки заголовка в component_epilog.php, который выполняется всегда.

Что типично выносят в эпилог:

Важная деталь: в component_epilog.php доступен не весь $arResult, а только то, что компонент явно «протащил» через кэш специальным механизмом (в штатных компонентах для этого есть заранее подготовленные поля вроде $arResult с нужными ключами). Поэтому в эпилоге обычно работают с уже готовыми значениями (title, код раздела), а не с полными массивами данных.

<?php
// component_epilog.php — всегда вне кэша
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) die();

global $APPLICATION;

// Заголовок и крошки ставим на каждый запрос
$APPLICATION->SetTitle($arResult['NAME']);
$APPLICATION->AddChainItem($arResult['SECTION']['NAME'], $arResult['SECTION']['URL']);

style.css, script.js и подключение ресурсов

Каждый блок обычно тянет за собой свои стили и скрипты, и Битрикс даёт для этого штатный механизм. Если в папке шаблона компонента рядом с template.php лежат файлы style.css и script.js, платформа подключает их автоматически при выводе компонента. Ничего регистрировать руками не нужно — положили файлы, и они поедут вместе с блоком.

Это предпочтительный способ, потому что такие ресурсы попадают в общий механизм объединения и минимизации: Битрикс собирает все style.css компонентов страницы в один файл, что сокращает число запросов. Плюс стили и скрипты «путешествуют» вместе с шаблоном — скопировали шаблон в свой namespace, и его оформление переехало вместе с ним.

Когда нужно подключить что-то дополнительно — внешний файл, строку в <head>, библиотеку, — используют API ядра, а не ручную вставку тегов:

<?php
// В template.php или result_modifier.php
$this->addExternalCss($templateFolder . '/vendor/slick.css');
$this->addExternalJs($templateFolder . '/vendor/slick.min.js');

// Строка прямо в head (например, preload или мета)
$APPLICATION->AddHeadString('<link rel="preload" as="image" href="/hero.webp">');

// Штатная библиотека ядра (jQuery, popup и т. п.)
\Bitrix\Main\UI\Extension::load('ui.notification');
Антипаттерн: вставлять <script> и <link> прямо в середину вёрстки template.php. Это ломает объединение ресурсов, приводит к дублям подключений и мешает композиту. Стили — в style.css, скрипты — в script.js или через addExternalJs; строки в head — только через AddHeadString.

Языковые файлы и локализация

Тексты интерфейса в шаблонах не пишут прямо в вёрстку — их выносят в языковые файлы. Это позволяет менять формулировки и переводить сайт, не трогая разметку. У шаблона компонента для этого есть папка lang/ с подпапками по языкам (ru, en), где лежит файл с сообщениями, повторяющий имя шаблона.

Работает это через функцию GetMessage(). В языковом файле объявляют константы-сообщения, а в шаблоне подставляют их по коду:

<?php
// lang/ru/template.php
$MESS['CATALOG_ADD_TO_CART'] = 'В корзину';
$MESS['CATALOG_NOT_AVAILABLE'] = 'Нет в наличии';
<?php
// template.php — подстановка перевода
<button class="buy"><?= GetMessage('CATALOG_ADD_TO_CART') ?></button>

Для интернет-магазина это не абстрактная возможность, а практическая гигиена. Даже на одноязычном сайте вынос текстов в lang упрощает правки: контент-менеджер или разработчик меняет формулировку кнопки в одном месте, а не ищет её по всей вёрстке. А если проект вырастет до второго языка, основа для локализации уже заложена. При кастомизации шаблона языковые файлы копируются вместе с ним, так что переводы не теряются.

$arResult и $arParams: контракт данных

Два массива связывают все уровни компонента воедино, и их стоит понимать точно. $arParams — это то, что входит в компонент: настройки, которые вы задаёте при его вызове. $arResult — это то, что компонент подготовил для вывода: собранные данные. Первый — вопрос, второй — ответ.

$arParams формируется из параметров вызова компонента и описания в .parameters.php. Сюда попадают ID инфоблока, число элементов на странице, сортировка, флаги «показывать цену», «включить кэш» и десятки других настроек. Компонент читает $arParams и по ним решает, что и как выбирать. Шаблон тоже видит $arParams и может подстраивать вывод под настройки.

$arResult — результат работы компонента: массив с данными. Для списка товаров это, как правило, $arResult['ITEMS'] с полями каждого товара (название, картинки, цена, свойства, URL). Именно этот массив выводит шаблон и дорабатывает result_modifier. Структура $arResult у штатных компонентов документирована, и лучший способ её изучить — вывести массив на экран при отладке.

<?php
// Быстрый способ увидеть структуру данных в template.php
echo '<pre>';
print_r($arResult['ITEMS'][0]);   // один товар со всеми полями
echo '</pre>';

Понимание контракта $arParams → $arResult и есть ключ к кастомизации. Хотите изменить вывод — работаете с $arResult в шаблоне и модификаторе. Хотите изменить, какие данные приходят, — управляете $arParams при вызове или (в крайнем случае) пишете свой компонент. Почти никогда не нужно лезть в саму логику штатного компонента: контракт данных даёт достаточно рычагов.

Поток данных: $arParams → компонент → $arResult → шаблон $arParams настройки вызова IBLOCK_ID, сорт. Компонент выборка из базы формирует данные $arResult готовые данные ITEMS[...] template → HTML Кастомизация вывода = работа с $arResult в шаблоне и result_modifier логику компонента при этом трогать не нужно
Схема: параметры вызова становятся $arParams, компонент по ним формирует $arResult, а шаблон превращает $arResult в HTML — кастомизация вывода идёт именно на уровне $arResult.

Кастомизация: копируем шаблон в свой namespace

Мы подошли к главному практическому навыку — правильной кастомизации. Правило номер один: не править ядро. Всё, что лежит в /bitrix/components/bitrix/ и /bitrix/templates/.default/, принадлежит платформе и перезаписывается при обновлении. Любая ваша правка там будет молча потеряна на ближайшем апдейте — а обновления в Битриксе выходят регулярно.

Правильный путь — копирование шаблона компонента в свой шаблон сайта. Платформа при выводе компонента ищет его шаблон по цепочке приоритетов: сначала в вашем шаблоне сайта, потом в общем .default, потом в самом компоненте. Значит, достаточно положить свою копию шаблона в нужную папку — и Битрикс возьмёт именно её, не трогая ядро.

  1. Найдите исходный шаблон. Штатный шаблон компонента лежит в /bitrix/components/bitrix/имя.компонента/templates/.default/.
  2. Скопируйте его в свой шаблон сайта. Путь назначения — /bitrix/templates/ваш_шаблон/components/bitrix/имя.компонента/имя_шаблона/ (или аналогично в /local/).
  3. Не меняйте имена файлов. template.php, result_modifier.php, style.css, папка lang — всё сохраняет имена, иначе платформа не подхватит.
  4. Правьте только копию. Меняйте вёрстку в template.php, данные — в result_modifier.php; исходник в bitrix/ остаётся нетронутым.
  5. Проверьте приоритет. Убедитесь, что компонент вызван с тем именем шаблона, которое вы скопировали (параметр TEMPLATE_NAME при вызове).

Есть и удобный способ сделать копию через интерфейс: в режиме правки на публичной странице у компонента в меню есть пункт «Копировать шаблон компонента» — он создаёт копию в вашем шаблоне сайта автоматически, с правильными путями. Для новичка это самый безопасный вариант: платформа сама разложит файлы куда надо.

Кастомизация без правки ядра /bitrix/components/bitrix/… штатный template.php НЕ ТРОГАЕМ перезапишется при обновлении /bitrix/templates/ваш/components/… ваша копия template.php ПРАВИМ ЗДЕСЬ переживает обновления копируем Приоритет поиска шаблона платформой ваш шаблон сайта → .default → компонент
Схема: штатный шаблон в bitrix остаётся нетронутым, вы копируете его в свой шаблон сайта и правите копию — платформа находит вашу версию первой и обновления её не затирают.

Кастомизация комплексного компонента

С простым компонентом всё прямолинейно: скопировали один шаблон, поправили. С комплексным (например, bitrix:catalog) чуть тоньше, потому что шаблонов там несколько уровней. Важно понимать, какой именно вы правите, иначе легко «менять не тот файл».

У комплексного компонента есть собственный шаблон — он отвечает за общую разметку каталога и за то, какие вложенные компоненты и с какими параметрами вызываются на каждой странице. А у каждого вложенного простого компонента (список товаров, карточка) — свой шаблон. Отсюда два сценария кастомизации:

Практическая подсказка: если вы правите шаблон комплексного компонента, но вёрстка карточки не меняется — почти наверняка вам нужен шаблон вложенного catalog.element, а не общий. И наоборот: если хотите поменять расположение фильтра и списка на странице раздела в целом — это уровень комплексного компонента. Определив уровень, дальше действуете по той же схеме копирования, что и с простым компонентом.

Совет по диагностике: в режиме правки Битрикс подсвечивает границы компонентов и показывает их имена и пути к шаблонам. Наведите на нужный блок — увидите, какой именно компонент и шаблон его рисует. Это лучший способ не ошибиться уровнем при кастомизации комплексного компонента.

API вызова компонента IncludeComponent

Компонент попадает на страницу через единый метод — $APPLICATION->IncludeComponent(). Это тот самый вызов, который вы видите в теле страниц и в шаблонах. Понимание его сигнатуры снимает большую часть вопросов «как передать параметр» и «как выбрать шаблон».

<?php
$APPLICATION->IncludeComponent(
    'bitrix:catalog.section',   // имя компонента (namespace:component)
    'shop_list',                // имя шаблона компонента
    array(                      // $arParams — параметры вызова
        'IBLOCK_ID'    => 12,
        'SECTION_CODE' => $sectionCode,
        'PAGE_ELEMENT_COUNT' => 24,
        'CACHE_TYPE'   => 'A',              // 'A' = Авто (теговый кэш)
        'CACHE_TIME'   => 36000000,
        'SET_TITLE'    => 'Y',
    ),
    false                       // родительский компонент (для вложенных)
);

Разберём аргументы. Первый — имя компонента в формате namespace:component: bitrix: — это штатное пространство имён; у своих компонентов будет свой namespace. Второй — имя шаблона: пустая строка означает .default, иначе платформа возьмёт именованный шаблон (и именно его копию она будет искать в вашем шаблоне сайта). Третий — массив параметров, которые станут $arParams. Четвёртый нужен только для вложенных вызовов внутри комплексных компонентов.

Здесь же задаётся кэш: CACHE_TYPE => 'A' включает режим «Авто» (теговый кэш), а SET_TITLE, SEF_MODE и десятки других флагов управляют поведением. Всё, что вы видите в форме настроек компонента в админке, — это тот же массив параметров, просто через визуальный интерфейс. Понимание, что настройки компонента = $arParams = аргумент IncludeComponent, связывает воедино админку и код.

Включаемые области и SEF include areas

Не всё на странице удобно держать в компонентах. Небольшие редактируемые куски — телефон в шапке, текст акции, врезка под баннером, — которые контент-менеджер должен править без программиста, выносят во включаемые области (include areas). Это отдельные файлы, которые подключаются в нужном месте и редактируются прямо на публичной части в визуальном режиме.

Технически это вызов $APPLICATION->IncludeFile() или компонент bitrix:main.include, который подключает файл-фрагмент. Такой фрагмент можно редактировать через панель управления как обычную страницу — без доступа к коду. Включаемые области бывают трёх типов охвата: для всего сайта, для раздела и для конкретной страницы.

<?php
// Включаемая область: текст, редактируемый на публичке
$APPLICATION->IncludeComponent(
    'bitrix:main.include',
    '',
    array(
        'AREA_FILE_SHOW'   => 'file',
        'PATH'             => '/include/promo_top.php',
        'EDIT_TEMPLATE'    => '',
    )
);

Отдельная история — SEF include areas в комплексных компонентах и разделах. Когда каталог работает в режиме ЧПУ, включаемые области привязываются к «виртуальным» страницам (раздел, элемент), чтобы, например, показать редактируемый текст под конкретной категорией. Это удобно для SEO-текстов разделов: контент-менеджер правит описание категории прямо на странице, а платформа хранит его в привязанном файле. Как такие тексты и фильтры влияют на SEO каталога, мы разбираем в статье про умный фильтр в 1С-Битрикс.

Кэш компонентов и шаблонов

Фронтенд и кэш в Битриксе неразделимы, и разработчику вёрстки важно понимать, что именно кэшируется. У каждого компонента есть свой кэш: собранный $arResult и отрисованный шаблон сохраняются и при следующем запросе отдаются готовыми, без обращения к базе. В режиме «Авто» этот кэш сбрасывается по тегам при изменении данных.

Ключевое для вёрстки — что попадает в кэш, а что нет. Мы уже видели это по частям, соберём вместе:

Часть шаблонаВ кэше?Что из этого следует
result_modifier.phpДаТяжёлую доводку данных считают один раз — держите её здесь
template.phpДаВывод кэшируется; не ставьте здесь то, что должно быть каждый запрос
component_epilog.phpНетЗаголовок, крошки, счётчики — только сюда
style.css / script.jsПодключаются всегдаРесурсы блока едут независимо от кэша данных

Из этой таблицы вытекают два железных правила фронтенда Битрикса. Первое: тяжёлое и повторяемое — в кэшируемые части (модификатор, шаблон), чтобы не считать это на каждый запрос. Второе: то, что должно меняться каждый запрос (заголовок, крошки, персональное), — в эпилог или в некэшируемые области, иначе оно «залипнет» на закэшированном значении. Нарушение первого правила даёт медленный сайт, второго — баги вроде одинакового title у всех страниц.

Тема кэша обширна: уровни, теги, хранилище, прогрев, инвалидация после обмена с 1С. Если хотите разобраться системно, у нас есть подробный разбор про кэширование в 1С-Битрикс — он логично продолжает эту статью там, где заканчивается вёрстка и начинается производительность.

Композит и динамические области

Композит — следующий уровень над кэшем компонентов. Он кэширует всю собранную HTML-страницу как статику и отдаёт её мгновенно, ещё до запуска тяжёлого ядра, а персональные блоки (корзину, авторизацию, имя пользователя) помечает динамическими областями и догружает отдельным быстрым запросом. Для фронтенда это накладывает конкретные требования к тому, как вы верстаете блоки.

Главное правило: персональное должно быть отделимо. Если корзина в шапке, блок авторизации и кнопка «купить/в корзине» вынесены в аккуратные компоненты, их легко пометить динамическими — и статика закэшируется, а персональное оживёт поверх. Если же персональные данные «размазаны» по общей вёрстке (например, имя пользователя вставлено прямо в разметку шапки без обёртки), композит либо не сможет их отделить, либо закэширует чужие данные для всех.

Как именно устроены динамические области, что выносить в динамику и как не сломать корзину при включении композита — тема отдельного подробного материала про композитный сайт в 1С-Битрикс. А как всё это отражается на метриках скорости, которые видит поиск, — в статье про Core Web Vitals для интернет-магазина. Здесь важно запомнить: грамотная компонентная вёрстка — необходимое условие того, чтобы композит вообще заработал.

Когда писать собственный компонент

Соблазн написать свой компонент возникает часто, но в большинстве случаев он не нужен: задачу решают шаблон и параметры штатного компонента. Тем не менее бывают ситуации, когда собственный компонент оправдан. Важно различать эти случаи, чтобы не плодить лишний код и не переусложнять проект.

ЗадачаРешение
Изменить внешний вид блокаКопия шаблона компонента
Добавить вычисляемое поле в выводresult_modifier.php
Изменить набор/сортировку выбираемых данныхПараметры $arParams при вызове
Нестандартная выборка, которой нет в штатныхСвой компонент
Интеграция с внешним API как источникомСвой компонент
Сложная бизнес-логика блокаСвой компонент

Если решение — свой компонент, его делают по той же стандартной структуре: папка с component.php (или class.php), .parameters.php, .description.php и папкой templates. Кладут его в собственное пространство имён (не в bitrix:, а, скажем, в ваш_проект:) и в папку local/components/ или bitrix/components/ваш_проект/. Логику получения данных пишут в component.php, а вывод — в шаблоне, ровно как у штатных. Так ваш компонент вписывается в общую модель: у него будет свой кэш, свои параметры, своя кастомизация шаблоном.

Практический ориентир: пишите свой компонент, только когда штатные не дают нужной логики данных. Если вопрос в вёрстке или в наборе полей — это уровень шаблона и модификатора, и свой компонент тут избыточен. Чем меньше кастомного кода, тем проще проект поддерживать и обновлять.

Инструменты отладки и публичная правка

Работать с фронтендом Битрикса вслепую тяжело — но платформа даёт хорошие инструменты, чтобы видеть, что происходит. Их стоит освоить до того, как приступать к кастомизации.

Отдельно про публичную правку контента. Включаемые области и обычные страницы редактируются прямо на сайте в визуальном режиме — это удобно для контент-менеджера, но требует дисциплины: правки идут в файлы, и их стоит держать под контролем версий, а не только «на бою». Разделяйте роли: код и шаблоны — задача разработчика в репозитории, тексты включаемых областей — задача контент-менеджера на публичке.

Частые ошибки

Большинство проблем с фронтендом Битрикса повторяются из проекта в проект. Зная их заранее, вы сэкономите дни отладки и убережёте проект от «неубиваемых» багов.

Чек-лист по фронтенду

Короткий список, по которому удобно свериться при разработке и перед релизом магазина на Битриксе:

Вывод

Фронтенд магазина на 1С-Битрикс перестаёт казаться «магией», как только видишь его слоями: шаблон сайта задаёт общую рамку, компоненты наполняют рабочую область блоками с логикой, а шаблоны компонентов отвечают за то, как эти блоки выглядят. Простой компонент выводит один блок, комплексный (как bitrix:catalog) управляет несколькими страницами по ЧПУ и вызывает простые внутри себя. Внутри компонента данные проходят конвейер component.php → result_modifier → template.php, а некэшируемое живёт в component_epilog.php.

Практический стержень всей работы — кастомизация без правки ядра. Копируете шаблон компонента в свой шаблон сайта или в local, правите копию, держите вёрстку чистой, доводку данных — в модификаторе, заголовки и крошки — в эпилоге, ресурсы — штатным механизмом, тексты — в lang. Тогда проект обновляется без потерь, работает быстро за счёт кэша и композита и легко передаётся другому разработчику. Это и есть зрелый фронтенд на Битриксе — аккуратный, обновляемый и производительный. Если нужен такой фронтенд под ваш проект, мы собираем его в рамках корпоративного сайта на Битриксе и интернет-магазина на Битриксе. Другие материалы по архитектуре и производительности собраны в рубрике «Разработка и архитектура».

Частые вопросы

Чем шаблон сайта отличается от шаблона компонента в 1С-Битрикс?

Это два разных уровня вёрстки. Шаблон сайта — это «рамка» всех страниц: шапка, подвал, подключение стилей и скриптов, общая сетка. Технически он живёт в bitrix/templates/имя_шаблона и состоит в основном из header.php и footer.php, между которыми выводится рабочая область страницы. Шаблон компонента — это вёрстка одного конкретного блока (списка товаров, меню, формы), он лежит внутри компонента и отвечает только за то, как отрисовать данные этого компонента. Проще говоря, шаблон сайта задаёт общий каркас, а шаблоны компонентов наполняют рабочую область конкретными блоками.

Что такое комплексный компонент и чем он отличается от простого?

Простой компонент выводит один блок и работает на одной странице — например, bitrix:menu или bitrix:catalog.section (список товаров раздела). Комплексный компонент управляет сразу несколькими логическими страницами и внутри себя вызывает простые компоненты. Классический пример — bitrix:catalog: он сам разбирает адрес (ЧПУ), понимает, что открыто — список разделов, список товаров или карточка, — и подключает нужный простой компонент. Поэтому у комплексного компонента есть настройки ЧПУ (SEF) и свои шаблоны для каждой страницы, а у простого — только вывод одного блока.

Можно ли править шаблоны компонентов прямо в папке bitrix?

Нет, это главная ошибка новичка. Всё, что лежит в /bitrix/components/bitrix/ и /bitrix/templates/.default/, принадлежит ядру и перезаписывается при обновлении платформы. Любая правка там будет молча потеряна на ближайшем апдейте. Правильный путь — скопировать шаблон компонента в свой шаблон сайта (в папку components внутри вашего шаблона) и менять уже эту копию. Ядро при этом остаётся нетронутым, а платформа при выводе компонента сначала ищет ваш шаблон и только потом штатный.

Зачем нужен result_modifier.php, если есть template.php?

result_modifier.php нужен, чтобы отделить подготовку данных от вёрстки. Он выполняется до template.php и до кэша шаблона: в нём удобно дополнить или преобразовать массив $arResult — добавить вычисляемые поля, отформатировать цену, подтянуть связанные данные. Благодаря тому, что result_modifier попадает в кэш, тяжёлая доводка данных считается один раз, а не на каждый запрос. В template.php тогда остаётся только чистый вывод. Это делает шаблон читаемым и не смешивает логику с HTML.

Что такое component_epilog.php и почему он работает даже при включённом кэше?

component_epilog.php — это код шаблона, который выполняется всегда, вне кэша компонента, после того как основная часть отдана (из кэша или собрана заново). Именно поэтому в эпилог выносят то, что не должно кэшироваться или должно отработать каждый запрос: установку заголовка страницы и хлебных крошек, подсчёт просмотров, регистрацию некоторых ресурсов. Если положить такой код в template.php, при попадании в кэш он просто не выполнится, и, например, заголовок страницы «залипнет». Эпилог решает эту проблему.

Как подключить свой CSS и JS к шаблону компонента правильно?

У шаблона компонента есть штатные файлы style.css и script.js: если они лежат рядом с template.php, платформа подключает их автоматически при выводе компонента. Это предпочтительный способ — стили и скрипты блока едут вместе с его шаблоном и попадают в общий набор ресурсов страницы. Если нужно подключить внешний файл или строку в head, используют API ядра — методы вроде addExternalCss, addExternalJs и AddHeadString. Главное — не вставлять теги script и link «руками» в середину вёрстки: это ломает объединение и минимизацию ресурсов.

Когда стоит писать собственный компонент, а когда хватит кастомизации шаблона?

Если задача — изменить внешний вид или слегка дополнить данные готового блока, почти всегда достаточно скопировать и отредактировать шаблон компонента (плюс result_modifier для данных). Свой компонент оправдан, когда нужна принципиально другая логика получения данных, которой нет в штатных компонентах: нестандартная выборка, интеграция с внешним источником, сложная бизнес-логика блока. Правило простое: сначала пытаемся решить задачу шаблоном и параметрами штатного компонента, и только если это невозможно — пишем свой компонент по стандартной структуре.

Как компоненты уживаются с композитом и кэшированием?

Компоненты — основа кэширования: у каждого есть свой кэш, который в режиме «Авто» сбрасывается по тегам при изменении данных. Композит стоит уровнем выше и кэширует всю собранную страницу как статику, а персональные блоки (корзину, авторизацию) помечает динамическими областями и догружает отдельно. Для фронтенда это значит: вёрстку и логику блоков строят так, чтобы кэшируемое было отделено от персонального. Тяжёлую доводку данных держат в result_modifier (он в кэше), а некэшируемое — в component_epilog или в динамических областях композита. Тогда шаблоны быстрые, а страница отдаётся мгновенно.

Поделиться:

Нужен аккуратный фронтенд на 1С-Битрикс?

Соберём и кастомизируем шаблоны и компоненты без правки ядра, наладим кэш и композит, сделаем вёрстку чистой и обновляемой. Рассчитаем работу по вашему проекту.

Игорь Воскресенский

Команда студии B2Bsite. С 2014 года разрабатываем, ускоряем и поддерживаем интернет-магазины на 1С-Битрикс: шаблоны и компоненты, кастомизация без правки ядра, кэш и композит, Core Web Vitals и обмен с 1С для среднего и крупного бизнеса.

← Все статьи блога