Перейти к содержимому

Шаблон чужого компонента - копия, доработка результата, эпилог

Доводим штатный компонент до нужного вида без правки платформы: копируем шаблон, меняем данные до вывода и догружаем то, чего в результате нет.

Решение

Копируем шаблон в свой каталог:

/bitrix/components/bitrix/news.list/templates/.default/ - исходный шаблон
/local/templates/main/components/bitrix/news.list/vitrina/ - копия под правку
template.php - разметка
result_modifier.php - правка данных до разметки
component_epilog.php - то, что нужно даже при готовом кэше
style.css, script.js - подключаются платформой сами

Копия живёт рядом с сайтом, а не внутри каталога платформы. Имя каталога и есть имя шаблона: его указывают параметром вызова, и с этого момента компонент рисует именно вашу разметку.

Меняем данные до вывода:

// result_modifier.php рядом с template.php
foreach ($arResult['ITEMS'] as &$item) {
$item['NAME_SHORT'] = mb_substr($item['NAME'], 0, 40); // готовим к выводу
unset($item['PROPERTIES']['SECRET']); // лишнее в шаблон не пускаем
}
unset($item);
// ссылку в цикле обязательно сбрасывают, иначе последний элемент задвоится
// сюда же складывают всё, что считается один раз и попадает в кэш

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

Догружаем то, чего нет в кэше:

// component_epilog.php: выполняется всегда, даже при готовом кэше
$APPLICATION->SetTitle($arResult['NAME']);
$APPLICATION->AddChainItem($arResult['NAME'], $arResult['DETAIL_PAGE_URL']);
// сюда же кладут счётчик просмотров и всё, что зависит от текущего пользователя

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

Подключаем свои стили и скрипты:

// файлы style.css и script.js рядом с template.php подключаются сами
// а вот дополнительный файл просят явно
$this->addExternalCss($templateFolder . '/vitrina.css');
$this->addExternalJs($templateFolder . '/vitrina.js');

Пара файлов с зарезервированными именами подключается платформой без вызовов. Всё остальное просят явно и указывают путь через переменную шаблона, чтобы копия шаблона работала на любом сайте.

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

Разметку правят в шаблоне, а данные - в доработке результата. Запрос к базе, случайно оказавшийся внутри разметки, выполняется на каждом показе страницы и мимо кэша компонента.

Имя шаблона стоит выбирать по смыслу, а не по номеру. Каталоги вроде «новый» и «новый2» через год не отличит даже их автор, а удалить лишний уже страшно.

Типичные проблемы

Правки шаблона пропали после обновления.

Менялся файл внутри каталога самой платформы. Обновление возвращает такие файлы в исходный вид.

Изменения в шаблоне не видны на сайте.

Страница отдаётся из кэша компонента, собранного до правки. Кэш сбрасывают или отключают на время работы.

Заголовок страницы обновляется через раз.

Он ставится в самом шаблоне, а тот при готовом кэше не выполняется. Такие вызовы переносят в эпилог.

Свой файл стилей не подключился.

Его имя отличается от зарезервированного, а явного подключения нет. Платформа сама подключает только два известных ей файла.

Страница с компонентом стала заметно медленнее.

В разметке появился запрос к базе или к внешнему сервису. Данные готовят в доработке результата, попадающей в кэш.

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

Чем доработка результата лучше правок в разметке?

Она попадает в кэш и выполняется один раз. Тот же код в разметке считается при каждом показе страницы.

Как узнать, что лежит в результате компонента?

Вывести массив результата в шаблоне отладочной печатью. Состав полей у разных компонентов заметно отличается.

Можно ли поменять сам запрос компонента?

Только через параметры вызова или свой компонент. Шаблон работает уже с готовой выборкой.

Куда класть шаблон, общий для двух сайтов?

В каталог шаблонов вне конкретного шаблона сайта. Тогда оба сайта берут одну копию, а не две расходящиеся.

Смежное

Первоисточник