Новый разработчик открывает проект на 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; компоненты с отключённым кэшем «на время отладки», забытые в продакшене. Всё это лечится одним — пониманием слоёв фронтенда, к которому мы и переходим.
Три уровня фронтенда: сайт, компоненты, их шаблоны
Первое, что нужно уложить в голове, — фронтенд Битрикса собирается из трёх вложенных уровней. Они не конкурируют, а вкладываются друг в друга, как матрёшка: шаблон сайта задаёт рамку, внутри рамки работают компоненты, а каждый компонент рисуется своим шаблоном.
- Шаблон сайта. Общая «рамка» всех страниц: шапка, подвал, подключение стилей и скриптов, сетка. Один шаблон сайта — единый внешний вид для сотен страниц.
- Компоненты. Самостоятельные блоки, которые получают данные и умеют себя выводить: меню, список товаров, карточка, форма, хлебные крошки. Компонент инкапсулирует логику и не зависит от того, на какой странице он стоит.
- Шаблоны компонентов. Вёрстка конкретного компонента: как именно отрисовать полученные данные в HTML. У одного компонента может быть несколько шаблонов под разные задачи.
Ключевая мысль: страница в Битриксе — это шаблон сайта, в рабочую область которого вставлены вызовы компонентов, а каждый компонент отрисован своим шаблоном. Когда вы понимаете, на каком уровне находится нужная правка, вопрос «где менять» отпадает сам собой. Дальше разберём каждый уровень по отдельности, начиная с внешней рамки — шаблона сайта.
Шаблон сайта: 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/ (там свои 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.element | bitrix:catalog, bitrix:news |
| Шаблонов у компонента | Один основной | Свой на каждую страницу + вложенных |
Практический вывод: если вам нужен один блок на конкретной странице (список товаров в разделе, который вы сверстали сами), берёте простой компонент. Если нужен «каталог целиком» с разделами, товарами, карточками и ЧПУ из коробки — берёте комплексный. Кастомизация у них устроена похоже, но у комплексного шаблонов больше, потому что каждой внутренней странице соответствует свой.
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 — служебные: первый описывает, какие настройки покажутся в форме компонента, второй — как компонент называется и где лежит в дереве выбора. При кастомизации вёрстки их обычно не трогают вовсе.
Шаблон компонента: 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, который выполняется всегда.
Что типично выносят в эпилог:
- Заголовок страницы и мета-теги —
SetTitle,SetPageProperty: они должны ставиться на каждый запрос. - Хлебные крошки —
AddChainItem: навигационная цепочка формируется вне кэша. - Счётчики и статистика — подсчёт просмотров товара, который нельзя кэшировать.
- Некоторые ресурсы — регистрация ассетов, которая должна повторяться каждый запрос.
Важная деталь: в 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 при вызове или (в крайнем случае) пишете свой компонент. Почти никогда не нужно лезть в саму логику штатного компонента: контракт данных даёт достаточно рычагов.
Кастомизация: копируем шаблон в свой namespace
Мы подошли к главному практическому навыку — правильной кастомизации. Правило номер один: не править ядро. Всё, что лежит в /bitrix/components/bitrix/ и /bitrix/templates/.default/, принадлежит платформе и перезаписывается при обновлении. Любая ваша правка там будет молча потеряна на ближайшем апдейте — а обновления в Битриксе выходят регулярно.
Правильный путь — копирование шаблона компонента в свой шаблон сайта. Платформа при выводе компонента ищет его шаблон по цепочке приоритетов: сначала в вашем шаблоне сайта, потом в общем .default, потом в самом компоненте. Значит, достаточно положить свою копию шаблона в нужную папку — и Битрикс возьмёт именно её, не трогая ядро.
- Найдите исходный шаблон. Штатный шаблон компонента лежит в
/bitrix/components/bitrix/имя.компонента/templates/.default/. - Скопируйте его в свой шаблон сайта. Путь назначения —
/bitrix/templates/ваш_шаблон/components/bitrix/имя.компонента/имя_шаблона/(или аналогично в/local/). - Не меняйте имена файлов.
template.php,result_modifier.php,style.css, папкаlang— всё сохраняет имена, иначе платформа не подхватит. - Правьте только копию. Меняйте вёрстку в
template.php, данные — вresult_modifier.php; исходник вbitrix/остаётся нетронутым. - Проверьте приоритет. Убедитесь, что компонент вызван с тем именем шаблона, которое вы скопировали (параметр
TEMPLATE_NAMEпри вызове).
Есть и удобный способ сделать копию через интерфейс: в режиме правки на публичной странице у компонента в меню есть пункт «Копировать шаблон компонента» — он создаёт копию в вашем шаблоне сайта автоматически, с правильными путями. Для новичка это самый безопасный вариант: платформа сама разложит файлы куда надо.
Кастомизация комплексного компонента
С простым компонентом всё прямолинейно: скопировали один шаблон, поправили. С комплексным (например, bitrix:catalog) чуть тоньше, потому что шаблонов там несколько уровней. Важно понимать, какой именно вы правите, иначе легко «менять не тот файл».
У комплексного компонента есть собственный шаблон — он отвечает за общую разметку каталога и за то, какие вложенные компоненты и с какими параметрами вызываются на каждой странице. А у каждого вложенного простого компонента (список товаров, карточка) — свой шаблон. Отсюда два сценария кастомизации:
- Меняете общую обвязку или параметры вложенных компонентов. Тогда копируете и правите шаблон самого комплексного компонента — в нём находятся вызовы
catalog.section,catalog.elementи их настройки. - Меняете вёрстку конкретной страницы (например, карточки товара). Тогда копируете шаблон вложенного простого компонента (
catalog.element) — именно он рисует карточку.
Практическая подсказка: если вы правите шаблон комплексного компонента, но вёрстка карточки не меняется — почти наверняка вам нужен шаблон вложенного 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-страницу как статику и отдаёт её мгновенно, ещё до запуска тяжёлого ядра, а персональные блоки (корзину, авторизацию, имя пользователя) помечает динамическими областями и догружает отдельным быстрым запросом. Для фронтенда это накладывает конкретные требования к тому, как вы верстаете блоки.
Главное правило: персональное должно быть отделимо. Если корзина в шапке, блок авторизации и кнопка «купить/в корзине» вынесены в аккуратные компоненты, их легко пометить динамическими — и статика закэшируется, а персональное оживёт поверх. Если же персональные данные «размазаны» по общей вёрстке (например, имя пользователя вставлено прямо в разметку шапки без обёртки), композит либо не сможет их отделить, либо закэширует чужие данные для всех.
- Оборачивайте персональное в компоненты. Корзина, авторизация, персональная цена — отдельные блоки, которые можно пометить динамическими.
- Резервируйте место под динамику. Чтобы при догрузке персонального блока вёрстка не «прыгала» (это портит CLS), заранее задавайте размеры контейнера.
- Не мешайте кэшируемое с некэшируемым. Тяжёлый общий контент (каталог, карточка) кэшируется; персональное — в динамику. Их смешение ломает и то, и другое.
Как именно устроены динамические области, что выносить в динамику и как не сломать корзину при включении композита — тема отдельного подробного материала про композитный сайт в 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, а вывод — в шаблоне, ровно как у штатных. Так ваш компонент вписывается в общую модель: у него будет свой кэш, свои параметры, своя кастомизация шаблоном.
Практический ориентир: пишите свой компонент, только когда штатные не дают нужной логики данных. Если вопрос в вёрстке или в наборе полей — это уровень шаблона и модификатора, и свой компонент тут избыточен. Чем меньше кастомного кода, тем проще проект поддерживать и обновлять.
Инструменты отладки и публичная правка
Работать с фронтендом Битрикса вслепую тяжело — но платформа даёт хорошие инструменты, чтобы видеть, что происходит. Их стоит освоить до того, как приступать к кастомизации.
- Режим правки (публичка). На публичной странице в панели администратора включается режим правки: он подсвечивает границы компонентов, показывает их имена и пути к шаблонам, даёт меню «Копировать шаблон», «Настроить компонент», «Редактировать область». Это главный инструмент навигации по чужому проекту.
- Отладочная панель и профилировщик. Показывает время генерации страницы, число и время SQL-запросов, попадания и промахи кэша. Много запросов на страницу — кэш выключен или не срабатывает; мало запросов, но медленно — узкое место во фронтенде или в тяжёлой первой сборке.
- Вывод
$arResult. Простейшийprint_r($arResult)в шаблоне показывает всю структуру данных — незаменимо, когда нужно понять, какие поля доступны для вывода. - Проверка приоритета шаблона. Если правки не применяются, почти всегда дело в том, что компонент вызван с другим именем шаблона или копия лежит не в том шаблоне сайта. Режим правки покажет реальный путь к используемому шаблону.
Отдельно про публичную правку контента. Включаемые области и обычные страницы редактируются прямо на сайте в визуальном режиме — это удобно для контент-менеджера, но требует дисциплины: правки идут в файлы, и их стоит держать под контролем версий, а не только «на бою». Разделяйте роли: код и шаблоны — задача разработчика в репозитории, тексты включаемых областей — задача контент-менеджера на публичке.
Частые ошибки
Большинство проблем с фронтендом Битрикса повторяются из проекта в проект. Зная их заранее, вы сэкономите дни отладки и убережёте проект от «неубиваемых» багов.
- Правка шаблонов внутри
bitrix/. Самая частая и болезненная: правки в ядре теряются при обновлении. Всегда копируйте шаблон в свой шаблон сайта или вlocal. - Логика в
template.php. Выборки из инфоблоков и тяжёлая обработка прямо в вёрстке. Выносите данные вresult_modifier.php, вёрстку оставляйте чистой. - Заголовок и крошки в
template.php. При попадании в кэш они «залипают». ПереноситеSetTitleиAddChainItemвcomponent_epilog.php. - Отключённый кэш «на время отладки».
CACHE_TYPE => 'N', забытый в продакшене, — каждый клик пересобирает блок с нуля. Проверяйте тип кэша перед релизом. - Ручная вставка
<script>и<link>в вёрстку. Ломает объединение ресурсов и композит. Используйтеstyle.css,script.js,addExternalJs,AddHeadString. - Отсутствие экранирования вывода. Данные в HTML без
htmlspecialcharsbx()— это XSS и сломанная вёрстка. Экранируйте всё, что выводите. - Тексты прямо в вёрстке вместо
lang. Усложняет правки и перевод. Выносите строки интерфейса в языковые файлы. - Свой компонент там, где хватило бы шаблона. Лишний код ради задачи, решаемой модификатором и параметрами. Пишите свой компонент только ради новой логики данных.
- Персональное в общем кэше/статике композита. Корзина или имя пользователя, попавшие в кэш, показываются всем. Оборачивайте персональное в отдельные компоненты и динамические области.
Чек-лист по фронтенду
Короткий список, по которому удобно свериться при разработке и перед релизом магазина на Битриксе:
- Общая рамка (шапка, подвал) вынесена в шаблон сайта; правки идут в
header.php/footer.php, а не в каждой странице. - Кастомизация вёрстки блоков сделана копированием шаблонов в свой шаблон сайта или
local; ядроbitrix/не тронуто. - Вёрстка в
template.phpчистая: без выборок из базы и тяжёлой логики. - Доводка данных вынесена в
result_modifier.php(он в кэше и считается один раз). - Заголовок, мета и хлебные крошки установлены в
component_epilog.php, а не в шаблоне. - Стили и скрипты блоков лежат в
style.css/script.js; внешние — черезaddExternalCss/addExternalJs. - Тексты интерфейса вынесены в языковые файлы
lang. - Весь вывод данных экранирован (
htmlspecialcharsbx). - У витринных компонентов включён кэш (режим «Авто»), а не «Не кэшировать».
- Персональные блоки (корзина, авторизация, цены) обёрнуты в отдельные компоненты и готовы к динамике композита.
- Свои компоненты лежат в собственном namespace и
local/components, а не вbitrix:.
Вывод
Фронтенд магазина на 1С-Битрикс перестаёт казаться «магией», как только видишь его слоями: шаблон сайта задаёт общую рамку, компоненты наполняют рабочую область блоками с логикой, а шаблоны компонентов отвечают за то, как эти блоки выглядят. Простой компонент выводит один блок, комплексный (как bitrix:catalog) управляет несколькими страницами по ЧПУ и вызывает простые внутри себя. Внутри компонента данные проходят конвейер component.php → result_modifier → template.php, а некэшируемое живёт в component_epilog.php.
Практический стержень всей работы — кастомизация без правки ядра. Копируете шаблон компонента в свой шаблон сайта или в local, правите копию, держите вёрстку чистой, доводку данных — в модификаторе, заголовки и крошки — в эпилоге, ресурсы — штатным механизмом, тексты — в lang. Тогда проект обновляется без потерь, работает быстро за счёт кэша и композита и легко передаётся другому разработчику. Это и есть зрелый фронтенд на Битриксе — аккуратный, обновляемый и производительный. Если нужен такой фронтенд под ваш проект, мы собираем его в рамках корпоративного сайта на Битриксе и интернет-магазина на Битриксе. Другие материалы по архитектуре и производительности собраны в рубрике «Разработка и архитектура».