Тему моего первого поста в блоге навеяли темы на форуме, в которых обсуждалось как устанавливать заголовок страницы из компонента который кешируется.
Очень часто в целях поисковой оптимизации требуется установить особенный заголовок, не такой как у $arResult["NAME"], а например "Холодильники ".$arResult["NAME"]; и др.
Или нам требуется установить картинку раздела из компонента. Допустим на сайте есть внутренний вижуал, который меняется в зависимости от выбранного автомобиля. Пример. [spoiler] В этом случае мы в компоненте анализируем свойство "Картинка" у автомобиля, и ставим его в качестве картинки раздела. Поскольку компонент в коде шаблона находится ниже чем картинка, делать это надо с помощью отложенных функций. Т.е. в компоненте досдаточно вызвать $APPLICATION->SetPageProperty("cat_pic", "/images/mypic.jpg"); а потом в шаблоне вывести это свойство с помощью отложенной функции.
Но если компонент кешируется, то ни в его шаблоне, ни в result_modifier.php вызов $APPLICATION->SetPageProperty() не сработает.
Преимущества стандартных компонентов:
1) Сохраняются все преимущества обновления (а их в последнее время все больше и больше, например, ЧПУ с поддержкой символьных кодов).
2) Шаблоны гораздо легче и проще переносить из проекта в проект, чем самописные компоненты.
3) Стандартные компоненты проверены тысячами сайтов, и я уверен в их надежности и безопасности.
Вобщем, перейдем к делу.
Чтобы это все сработало - нам надо в файле result_modifier.php написать:
<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();
// Картинка категории - это картинка связанного элемента
if ($arResult["LINKED_ELEMENTS"][0]["ID"] > 0)
{
$el = CIblockElement::GetById($arResult["LINKED_ELEMENTS"][0]["ID"]);
$element = $el->GetNext();
if ($element["DETAIL_PICTURE"] > 0)
$pic = CFile::GetPath($element["DETAIL_PICTURE"]);
}
// Приклеиваем путь к картинке к ID элемента
$component = $this->__component;
$component->arResult["ID"] = $arResult["ID"]."|".$pic;
?>
Вся хитрость в том, что строчкой $component->arResult["ID"] = $arResult["ID"]."|".$pic; мы приклеиваем к результату работы компонента свои параметры.
При вызове компонента в шаблоне сайта результат его работы записываем в переменную $element_id:
<?$element_id=$APPLICATION->IncludeComponent("bitrix:catalog.element", "security", array(
... код вызова компонента ...
а после кода вызова компонента разбираем полученную строчку:
$arReturn = explode('|', $element_id);
if ($arReturn[1])
$APPLICATION->SetDirProperty("cat_pic", $arReturn[1]);
Чтобы сохранить совместимость, нам нужно чтобы на выходе компонента мы получили $ID элемента. Он используется при редактировании элементв "с лица". А поскольку все компоненты Битрикса, как я говорил, написаны очень грамотно и безопасно - во всех них делается проверка $ID = intval($ID); Поэтому система получает нормальный $ID и ничего лишнего.
Мы же можем разрбрать строку $ID, вытащить из неё картинку или любое другое свойство (или даже несколько свойств), и с помощью отложенных функций дальше делать с ними все что угодно.
Компоненты, настроенные таким образом, отлично кешируются, заголовки и свойства динамически устанавливаются и можно добиться чтобы сайт работал даже без соединения с базой данных.
Недостатки (а есть и такие):
1) Не все компоненты что-то возвращают. Хотя большинство элементов все же возвращают значения, есть и такие которые почему-то этого не делают. Так, элемент bitrix:catalog.sections почему-то в случае успеха возвращает 1, а не номер раздела.
Выход: использовать компонент bitrix:photo.section, он делает все правильно и возвращает номер раздела. Или же искать другой путь обхода.
2) При использовании визуального редактора если стоит строчка <?$element_id = $APPLICATION->IncludeComponent(... ?> то редактор не понимает что это компонент, и вместо него выводит код <?php?>. Что довольно странно, мне даже помнится раньше такое срабатывало. Надеюсь, в будущем разработчики исправят этот досадный недостаток, так как системой предусмотрено чтобы компоненты что-то возвращали, и это коррекнтный вызов компонента.
Выход: использовать такую конструкцию в комплексных компоненентах. Тогда в файле element.php можно подключать сразу несколько компонентов, и дописывать до и после них любой код, не переживая за визуальный редактор.
Еще один вариант - редактировать параметры компонентов перейдя на вкладку "Разработка" и нажав на "шестеренку". Компоненты, измененные таким образом отлично сохраняются и $element_id перед ними остается.
Все-же надеюсь в будущем разработчики добавят событие, или файл-обработчик в котором можно будет вызывать свои функции, а пока пользюсь этим методом, и очень доволен
UPD: На данный момент я на всех проектах использую "Супер компонент", в котором можно устанавливать любые динамические свойства из файла result_modifier_nc.php.
Я тоже столкнулся с тем, что нужно использовать частичное кеширование. Но не настолько я пока "могуч" в этом вопросе, что подумал, а если для вывода использовать template_nc.php куда можно получать и кешируемый $arResult с result_modifier.php и также не кешируемый с result_modifier_nc.php. Это ускорит вывод данных по сравнению с просто компонентом у которого отключено кеширование?
Очень часто в целях поисковой оптимизации требуется установить особенный заголовок
Т.е., если я хочу при выводе Элемента инфоблока, на основе содержимого элемента установить свой заголовок мне нужно: 1. в result_modifier.php сделать {$component->arResult["ELEMENTS"]["myproperty"]='заголовок+значение_свойства'} 2. а на индексной странице, где вызывается компонент, добавить $myresult перед вызовом компонента и после присвоить свойство страницы или папки, которое потом в можно будет использовать в шаблоне сайта?
component_epilog.php тоже спасает не от всего. Например что делать если в catalog.section нужно показать какие товары в корзине и какие нет? На форуме все делают через javascript который будет написан в component_epilog.php. То есть на мой взгляд это обратный костыль. Сервер знает какие товары лежат в корзине, но показать не может, и эта задача падает на сторону клиента.
Группы на сайте создаются не только сотрудниками «1С-Битрикс», но и партнерами компании. Поэтому мнения участников групп могут не совпадать с позицией компании «1С-Битрикс».