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

Текущий товар и раздел - как достать их в шаблоне и на странице

Достаём идентификатор открытого товара и раздела там, где он нужен, и не делаем ради этого повторную выборку.

Решение

Берём данные в шаблоне компонента:

// шаблон catalog.element: товар уже выбран, повторный запрос не нужен
printf("товар=%s раздел=%s имя=%s\n",
$arResult['ID'], $arResult['IBLOCK_SECTION_ID'], $arResult['NAME']);
// шаблон catalog.section: текущий раздел лежит в отдельном ключе
printf("раздел=%s\n", $arResult['SECTION']['ID'] ?? '-');

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

Достаём значения вне шаблона компонента:

// комплексный компонент кладёт их в свойства страницы
$elementId = $APPLICATION->GetPageProperty('ELEMENT_ID');
$sectionId = $APPLICATION->GetPageProperty('SECTION_ID');
// а сам адрес разобран правилом обработки: коды приходят в параметрах запроса
printf("код товара=%s\n", $_REQUEST['ELEMENT_CODE'] ?? '-');

Свойства страницы заполняются компонентом до вывода шаблона сайта. Поэтому в шапке и подвале они уже доступны, а вот до вызова компонента - ещё нет.

Находим элемент по символьному коду, если данных нет:

$res = CIBlockElement::GetList([], [
'IBLOCK_ID' => 5,
'CODE' => $_REQUEST['ELEMENT_CODE'],
'ACTIVE' => 'Y',
], false, ['nTopCount' => 1], ['ID', 'NAME', 'IBLOCK_SECTION_ID']);
$element = $res->GetNext();

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

Передаём значения включаемой области:

$APPLICATION->IncludeComponent('bitrix:main.include', '', [
'AREA_FILE_SHOW' => 'sect', // своя область на каждый раздел
'AREA_FILE_SUFFIX' => 'inc',
'EDIT_TEMPLATE' => '',
]);

Включаемая область раздела подхватывается по пути страницы, а не по идентификатору. У комплексного компонента физического пути раздела нет, поэтому области там задают своим кодом по коду раздела из адреса.

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

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

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

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

Идентификатор товара пуст в шапке сайта.

Шапка выводится до вызова компонента. Свойства страницы к этому моменту ещё не заполнены.

На странице лишние запросы к базе.

Код ищет товар, который компонент уже выбрал. Данные берут из результата компонента, а не повторной выборкой.

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

У раздела каталога нет своего пути на диске. Область выбирают своим кодом по коду раздела из адреса.

Свой код в шаблоне не выполняется на части запросов.

Шаблон компонента попал в кэш. Код, который должен работать всегда, выносят в эпилог компонента.

По коду из адреса находится не тот элемент.

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

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

Как получить раздел товара на детальной странице?

Из результата компонента: там лежит и основная привязка, и путь разделов. Отдельная выборка нужна только вне компонента.

Где узнать код текущего раздела?

В параметрах запроса: правило обработки адресов кладёт туда разобранные части пути. Имя параметра задаётся шаблоном адреса.

Можно ли передать данные из компонента в шаблон сайта?

Да, свойствами страницы: компонент заполняет их до вывода подвала. Шапка при этом уже отрисована, и туда данные не попадут.

Почему свой код видит старые данные?

Он читает закэшированный результат компонента. Актуальные значения берут в эпилоге компонента, который выполняется вне кэша.

Смежное

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