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

Важно: объект шаблона (
&$this->GetTemplate()
) доступен только после подключения шаблона методом$this->IncludeComponentTemplate()
. До этого моментаGetTemplate()
вернётnull
.
Когда и где доступен объект шаблона
Неправильно (объекта ещё нет):
<?php
// .class.php или .component.php (раньше времени)
$template = &$this->GetTemplate(); // null, шаблон ещё не инициализирован
?>
Правильно:
<?php
// .class.php или .component.php
$this->IncludeComponentTemplate(); // <- подключили шаблон
// ...любой ваш код после подключения шаблона
$template = &$this->GetTemplate(); // объект CBitrixComponentTemplate
$templateFile = $template->GetFile(); // путь к template.php
$templateFolder = $template->GetFolder(); // путь к папке шаблона
?>
Внутри template.php
переменная $this
— это сам CBitrixComponentTemplate
, а не компонент. Компонент доступен как $component
.
Быстрый справочник по часто используемым методам
GetSiteTemplate()
— имя шаблона сайта, где лежит шаблон компонента; системным шаблонам вернёт пустую строку.GetName()
— имя шаблона компонента.GetFolder()
— путь к папке шаблона относительно корня сайта (или пустая строка, если шаблон — одиночный файл).GetFile()
— путь к файлу шаблона относительно корня сайта.getComponent()
— вернёт экземплярCBitrixComponent
(с версии 15.5.10).addExternalCss()
— подключает внешний CSS (с версии 15.5.1).addExternalJs()
— подключает внешний JS (с версии 15.5.1).
Дополнительно (очень полезно):
SetViewTarget()/EndViewTarget()
— врезки в layout черезShowViewContent
.setFrameMode()/createFrame()
— композит.AddEditAction()/AddDeleteAction()/GetEditAreaId()
— области редактирования.IncludeLangFile()
— загрузка языковых файлов шаблона.GetPageName()
— возвращает имя страницы шаблона (например,template
).hasTemplate()
,hasTemplatePage()
— проверки наличия шаблона/страницы (актуально для поздних версий ядра).
Мини-компонент: структура и базовый пример
Файл .class.php
(класс компонента)
<?php
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();
class DemoTemplateAwareComponent extends CBitrixComponent
{
protected function prepareResult(): void
{
$this->arResult['ITEMS'] = [
['ID' => 1, 'TITLE' => 'Первый'],
['ID' => 2, 'TITLE' => 'Второй'],
['ID' => 3, 'TITLE' => 'Третий'],
];
}
public function executeComponent(): void
{
$this->prepareResult();
// Подключаем шаблон
$this->IncludeComponentTemplate();
// После подключения шаблона доступен объект CBitrixComponentTemplate:
$template = &$this->GetTemplate();
if ($template)
{
// Пример: получим пути
$file = $template->GetFile(); // /local/templates/..../components/.../template.php
$folder = $template->GetFolder(); // /local/templates/..../components/.../
// Здесь можно писать логику, опираясь на сведения о шаблоне
// file_put_contents($_SERVER['DOCUMENT_ROOT'].'/local/log.txt', $file.PHP_EOL, FILE_APPEND);
}
}
}
?>
Файл templates/.default/template.php
<?php if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();
/** @var CBitrixComponentTemplate $this */
/** @var CBitrixComponent $component */
/** @var array $arParams */
/** @var array $arResult */
// С версии 15.5.1 можно подключать внешние файлы:
$this->addExternalCss("/local/assets/css/common.css");
$this->addExternalJs("/local/assets/js/common.js");
// Композитный режим — указываем, что шаблон дружит с композитом
$this->setFrameMode(true);
// Языковые файлы шаблона (если нужны):
$this->IncludeLangFile(); // загрузит lang/<LANG>/template.php для этого template.php
// Пример врезки в layout (sidebar/footer/и т.п.)
$this->SetViewTarget('sidebar', 100);
?>
<div class="widget">
<div class="widget__title"><?=GetMessage('WIDGET_TITLE', ['#CNT#' => count($arResult['ITEMS'])]);?></div>
<div class="widget__body">Любой HTML для сайдбара</div>
</div>
<?php
$this->EndViewTarget();
// Список с областями редактирования
?>
<div class="list">
<?php foreach ($arResult['ITEMS'] as $item): ?>
<?php
// Области редактирования (появятся иконки в публичной части)
$this->AddEditAction(
'ITEM'.$item['ID'],
'/bitrix/admin/iblock_element_edit.php?ID='.$item['ID'],
GetMessage('EDIT_ITEM')
);
$this->AddDeleteAction(
'ITEM'.$item['ID'],
'/?action=delete&id='.$item['ID'],
GetMessage('DELETE_ITEM'),
['CONFIRM' => GetMessage('CONFIRM_DELETE')]
);
?>
<div id="<?=$this->GetEditAreaId('ITEM'.$item['ID']);?>" class="list__item">
<span class="list__title"><?=htmlspecialcharsbx($item['TITLE']);?></span>
<?php
// Пример частично динамического фрагмента в композите
$frame = $this->createFrame('time_'.$item['ID'])->begin();
echo '<small class="list__time">'.date('H:i:s').'</small>';
$frame->end();
?>
</div>
<?php endforeach; ?>
</div>
Файл templates/.default/lang/ru/template.php
<?php
$MESS['WIDGET_TITLE'] = 'Виджет (элементов: #CNT#)';
$MESS['EDIT_ITEM'] = 'Редактировать элемент';
$MESS['DELETE_ITEM'] = 'Удалить элемент';
$MESS['CONFIRM_DELETE'] = 'Удалить безвозвратно?';
?>
result_modifier.php
(опционально)
<?php if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();
// Здесь вы можете обогатить $arResult перед выводом шаблона
foreach ($arResult['ITEMS'] as &$item) {
$item['URL'] = '/catalog/'.$item['ID'].'/';
}
unset($item);
?>
component_epilog.php
(опционально)
<?php if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();
/** @var array $templateData */ // можно передать из template.php
/** @var string $templateFile */
/** @var string $templateFolder */
// Например, подключим ещё один JS уже после основного контента
global $APPLICATION;
$APPLICATION->AddHeadScript($templateFolder.'/late.js');
?>
Как передать
$templateData
вcomponent_epilog.php
:Внутри
template.php
просто установите$templateData = ['foo' => 'bar'];
— ядро само передаст массив.
Подключение внешних файлов (CSS, JS) из шаблона
С версии 15.5.1:
// Внутри template.php
$this->addExternalCss("/local/styles.css");
$this->addExternalJs("/local/lib.js"); // <-- верное имя метода (не addExternalJS)
Преимущества:
- файлы учитываются в кэше шаблона (ядро запоминает их и подключает на кэш-хитах);
- корректная агрегация через родительские компоненты при вложенных шаблонах.
Полезные приёмы
1) Быстрая диагностика путей шаблона (в коде компонента)
$this->IncludeComponentTemplate();
$template = &$this->GetTemplate();
if ($template)
{
$info = [
'SITE_TEMPLATE' => $template->GetSiteTemplate(),
'NAME' => $template->GetName(),
'PAGE' => method_exists($template, 'GetPageName') ? $template->GetPageName() : null,
'FOLDER' => $template->GetFolder(),
'FILE' => $template->GetFile(),
'IN_THEME' => method_exists($template, 'IsInTheme') ? $template->IsInTheme() : null,
];
// dump($info); // выведите в лог/панель разработчика
}
2) Доступ к самому компоненту из шаблона
// template.php
$component = $this->getComponent(); // CBitrixComponent
$params = $component->arParams;
$relPath = $component->GetRelativePath();
3) Врезки в layout через view targets
// template.php
$this->SetViewTarget('after_breadcrumbs', 200);
?>
<div class="promo">Промоблок после хлебных крошек</div>
<?php
$this->EndViewTarget();
// В header.php или другом layout:
$APPLICATION->ShowViewContent('after_breadcrumbs');
4) Композит: динамические куски
// template.php
$this->setFrameMode(true);
$frame = $this->createFrame()->begin();
// ... динамический HTML (например, время, счётчик, статус корзины)
echo '<span class="status">'.date('H:i:s').'</span>';
$frame->end();
5) Языковые файлы для разных частей шаблона
// В template.php, если нужен другой lang-файл:
$this->IncludeLangFile('partial.php'); // загрузит lang/<LANG>/partial.php
echo GetMessage('PARTIAL_TITLE');
6) Проверка наличия шаблона/страницы (актуально для современных версий)
$this->IncludeComponentTemplate();
$template = &$this->GetTemplate();
if (method_exists($template, 'hasTemplate') && !$template->hasTemplate()) {
// fallback, если каталог шаблона отсутствует
}
if (method_exists($template, 'hasTemplatePage') && !$template->hasTemplatePage('template')) {
// обработайте отсутствие файла страницы, если нужно
}
Кэш и «автоматические» файлы шаблона
Если в папке шаблона лежат style.css
и/или script.js
, ядро подключит их автоматически при IncludeTemplate
. Это же учитывается в кэше (см. внутренние методы GetCachedData()
/ ApplyCachedData()
), а также внешние файлы, добавленные через addExternalCss()/addExternalJs()
.
Частые ошибки и как их исправить
- Ранний вызов
GetTemplate()
Решение: вызывайте только после$this->IncludeComponentTemplate()
. - Неверный регистр метода подключения JS
Было:$this->addExternalJS('/path.js');
Правильно:$this->addExternalJs('/path.js');
- Забыли
EndViewTarget()
Решение: всегда закрывайтеSetViewTarget()
паройEndViewTarget()
; удобно оборачивать в try/finally, если внутри есть логика. - Вывод динамики без композит-рамки
Решение:setFrameMode(true)
+createFrame()->begin(); ... ->end();
. - Неправильная экранизация
Любые пользовательские данные выводим черезhtmlspecialcharsbx()
.
Расширенный пример (полезный каркас шаблона)
<?php if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();
/** @var CBitrixComponentTemplate $this */
/** @var CBitrixComponent $component */
/** @var array $arParams */
/** @var array $arResult */
// 1) Композит
$this->setFrameMode(true);
// 2) CSS/JS
$this->addExternalCss($this->GetFolder()."/assets/template.css");
$this->addExternalJs($this->GetFolder()."/assets/template.js");
// 3) Язык
$this->IncludeLangFile(); // lang/<LANG>/template.php
// 4) Врезка в шапку/сайдбар
$this->SetViewTarget('sidebar', 150);
?>
<aside class="box box--sticky">
<h3><?=GetMessage('SIDEBAR_TITLE');?></h3>
<p><?=GetMessage('SIDEBAR_TEXT');?></p>
</aside>
<?php
$this->EndViewTarget();
// 5) Контент
?>
<section class="cards">
<?php foreach ($arResult['ITEMS'] as $item): ?>
<?php
$id = (int)$item['ID'];
$safeTitle = htmlspecialcharsbx($item['TITLE']);
$this->AddEditAction(
'ITEM'.$id,
'/bitrix/admin/iblock_element_edit.php?ID='.$id,
GetMessage('EDIT_ITEM')
);
$this->AddDeleteAction(
'ITEM'.$id,
'/?action=delete&id='.$id,
GetMessage('DELETE_ITEM'),
['CONFIRM' => GetMessage('CONFIRM_DELETE')]
);
?>
<article id="<?=$this->GetEditAreaId('ITEM'.$id);?>" class="card">
<h4 class="card__title"><?=$safeTitle;?></h4>
<?php $frame = $this->createFrame('dyn_'.$id, true)->begin(); ?>
<div class="card__meta"><?=GetMessage('NOW_TIME')?>: <?=date('H:i:s');?></div>
<?php $frame->end(); ?>
<?php if (!empty($item['URL'])): ?>
<a class="card__link" href="<?=htmlspecialcharsbx($item['URL']);?>"><?=GetMessage('OPEN');?></a>
<?php endif; ?>
</article>
<?php endforeach; ?>
</section>
<?php
// 6) Передать данные в component_epilog.php
$templateData = [
'TIMESTAMP' => time(),
];
?>
lang/ru/template.php
для этого примера:
<?php
$MESS['SIDEBAR_TITLE'] = 'Боковая панель';
$MESS['SIDEBAR_TEXT'] = 'Любой текст виджета.';
$MESS['EDIT_ITEM'] = 'Редактировать';
$MESS['DELETE_ITEM'] = 'Удалить';
$MESS['CONFIRM_DELETE']= 'Вы уверены?';
$MESS['NOW_TIME'] = 'Время';
$MESS['OPEN'] = 'Открыть';
?>
Вопросы навигации и поиска шаблонов
Ядро ищет шаблоны по множеству путей (локальные/стандартные, в контексте родительского шаблона и сайта). В современных версиях доступны вспомогательные методы:
$this->IncludeComponentTemplate();
$template = &$this->GetTemplate();
// Есть ли папка шаблона?
if (method_exists($template, 'hasTemplate') && $template->hasTemplate()) {
// ...
}
// Есть ли конкретная страница внутри шаблона?
if (method_exists($template, 'hasTemplatePage') && $template->hasTemplatePage('template')) {
// ...
}
// Получить список возможных путей (для отладки/диагностики)
if (method_exists($template, 'generatePossibleTemplatePath')) {
$paths = $template->generatePossibleTemplatePath();
// print_r($paths);
}
Заключение
CBitrixComponentTemplate
— это не только «обёртка», но и мощный инструмент интеграции шаблона с ядром: подключение ресурсов, композит, локализация, врезки в layout, области редактирования, post-epilog и многое другое. Пользуйтесь им по назначению:
- получайте объект шаблона после
IncludeComponentTemplate()
; - подключайте CSS/JS через
addExternalCss()
/addExternalJs()
; - используйте
setFrameMode()
/createFrame()
для композита; - применяйте
SetViewTarget()
для гибкого layout; - помните про локализацию и экранирование.
Этот набор приёмов покрывает 99% практических задач при работе с шаблонами компонентов в 1С-Битрикс.