Ситуация усугубляется, если в шаблоне компонента подключается другой компонент. Тут же теряются стили дочернего компонента, происходят другие непонятные вещи. Такое поведение является "задокументированно-правильным", но разработчику от этого не легче.
Начиная с версии 9.0.0 ядра мы расширили возможности компонентов: теперь в закешированном компоненте можно исполнять код в шаблоне. Кроме того, стили дочернего компонента подключаются автоматически.[spoiler]
Как это работает?
1. Стили дочернего компонента. При первом исполнении шаблона дочерний компонент передает информацию вызывающему компоненту: "Друг, у меня тут есть файл(ы) стилей, учти это!". Родительский компонент сохраняет список файлов стилей в своем кеше. При хите в кеш извлекается список файлов и добавляется на страницу через $APPLICATION->SetAdditionalCSS(). Интересно, что поддерживаются вложенные вызовы компонентов, т.е. дочерний компонент передает не только свой файл стилей, но и файлы всех компонентов, которые он сам вызывает.
Чтобы такая схема заработала, необходимо, чтобы дочерний компонент знал, что его вызывает родительский компонент. Делается это через передачу в параметрах ф-ии $APPLICATION->IncludeComponent() объекта текущего компонента (переменная $component, доступная в шаблоне). Код template.php родительского компонента:
<?$APPLICATION->IncludeComponent( "my:genius.component", "", array( "PARAM"=>array(), ), $component );?> |
2. Код в шаблоне. При исполнении шаблона компонента в папке шаблона проверяется наличие файла component_epilog.php. Это файл подключается после исполнения шаблона. В нем доступны те же переменные, что и в шаблоне: $arParams, $arResult. Аналогично файлам стилей, родительский компонент сохраняет в своем кеше список файлов эпилогов всех шаблонов дочерних компонентов (возможно вложенных), а при хите в кеш подключает эти файлы в том же порядке, как они исполнялись без кеширования. Данные $arParams, $arResult при этом берутся из кеша. Точно так же при вызове дочерних компонентов в шаблоне нужно передавать значение $component.
В component_epilog.php может быть любой код - только следует учитывать, что исполняться он будет "мимо кеша" на каждом хите. Например, можно устанавливать заголовок страницы или подключать дополнительные стили или скрипты:
<? if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die(); $APPLICATION->AddHeadScript('/bitrix/js/main/utils.js'); $aGlobalOptions = CUserOptions::GetOption("main.interface", "global", array()); if($aGlobalOptions["theme"] <> '') $APPLICATION->SetAdditionalCSS($templateFolder.'/themes/'.$aGlobalOptions["theme"].'/style.css'); ?> |
Надеемся, что эти изменения в технологии компонентов помогут более широко использовать автокеширование в компонентах и сделают компоненты еще привлекательнее для разработчиков.
Кстати, обновление уже доступно: бегом тестировать!
Схемы они понагляднее будут.
По рисунку же кажется, что component_epilog.php отрабатывает после полного исполнения component.php
В документации не забудьте обновить
С нетерпением жду стабильного релиза обновлений.
Если вы в файле component_epilog.php используете какие-либо данные из $arResult, то для гарантированного их сохранения в кеше в template.php необходимо вызвать функцию $component->SetResultCacheKeys(array("key1", "key2", ...));.
Спасибо за доработку. Будем тестировать.
В итоге как кастомизировали компоненты так и продолжаем кастомизировать. component_epilog.php -- в топку..
Кстати, обновление уже доступно: бегом тестировать!
Спасибо! Поставил вчера обновление - оказалось сегодня утром что половина сайтов вообще не работают, в компонентах не подключаются стили и пр.
Отключил автокеширование - вроде лучше стало, однако все равно на некоторых страницах перестали подключатся компоненты когда в их шаблоне подключены другие компоненты.
Может, стоит сделать галочку "не использовать новый механизм работы компонентов"?
Так и инфаркт схватить можно, пока разрбрался в чем дело.
Если вы в файле component_epilog.php используете какие-либо данные из $arResult, то для гарантированного их сохранения в кеше в template.php необходимо вызвать функцию $component->SetResultCacheKeys(array("key1", "key2", ...));.
Либо стандартный компонент должен засовывать туда весь результат, это может быть очень много, на форуме была ветка, я решал проблему с местом на хостинге, SetResultCacheKeys позволил уменьшить файлы кеша на порядок.
Да и если засовывать все - то смысл от функции SetResultCacheKeys в стандартном компоненте.
Собственно если собираемся в component_epilog.php ставить титл из свойства "тра-та" иблока, то это свойство должно быть задано с помощью SetResultCacheKeys.
Поэтому не помешает настройка компонента позволяющая указать что именно из $arResult мы будем использовать в component_epilog.php
Это для начинающих конечно, тру девелоперы пишут свои компоненты
Разочарование: копонент catalog.element - при попытке установить заголовок в файле component_epilog.php, заголовок не менялся. Выяснилось код в файле component_epilog.php выполняется раньше кода в component.php, который находится ниже подключения шаблона. Т.е. новый заголовок все-равно перезаписывается старым.
Полагаю файл component_epilog.php инклюдиться после подключение шаблона, а потом выполняется оставшийся код component.php.
Так и задумывалось или это баг?
Вывод: Заголовок изменить новым функционалом не получилось. Пока других применений не нашел, по старому изменяю сами компоненты под себя?
- неуправляемый и управляемый кеш (папки /bitrix/cache/, /bitrix/managed_cache и /bitrix/stack_cache) - можно перенести в память (значения - memcache, APC, xCache)
- "HTML-кеш" (папка /html_pages/) - хранится только в файлах, независимо от значения 'cache' > 'type' в .settings.php (пн.1)
?