На одной из страниц нашего сайта применены сразу три разных способа, чтобы сделать некэшируемые области в стандартном компоненте.[spoiler]
Лирическое отступление:
Что такое HTML кэширование в стандартных компонентах?
Это, когда всё, что выводится в шаблоне компонента, временно сохраняется в файле. И пока время кэширования не истечёт, что-либо изменить невозможно: ни в файле template.php, ни в result_modifier.php. Эти файлы просто не вызываются.
Простейший пример, когда нужна некэшируемая область:
Надо отобразить кнопку «В корзину», но если товар уже добавлен, то писать «Товар в корзине».
Исправить можно только одним способом: необходимо парсить. Надо получить HTML компонента и в него вставить то, что нам надо.
В девятой версии Битрикса появился волшебный файлик component_epilog.php, а Евгений Лазарчик объяснил, как его можно использовать для такой задачи.
Но поскольку каталог на geodom.ru сделан до выхода девятой версии, парсить пришлось по-другому.
На странице товара на сайте geodom.ru сделаны некэшируемые области тремя способами:
Способ 1:
кнопка добавить в корзину / товар в корзине,
голосовалка «звёздочки»,
голосовалка «рука».
Способ 2:
отзывы о товаре с листалкой и сортировками. (news.list впихнут в catalog.element).
Способ 3:
ссылка подписаться / отписаться,
ссылка отложить / товар отложен.
Замечение. Голосовалка «рука» вставлена в отзыв о товаре (news.list), а значит последовательно применились способ 2 и 1.
На картинке отмечены некэшируемые области и способы, которыми они сделаны.
Как это выглядит:
Найдите 5 отличий:
Сначала.
После изменения некэшируемых областей.
Способ 1.
Самый универсальный способ по-битриксовски. Очень удобен, когда одну и ту же подстановку надо делать на разных страницах.
Обработка события OnEndBufferContent. Парсим код всей страницы.
В файле init.php:
AddEventHandler("main", "OnEndBufferContent", "ChangeMyContent");
function ChangeMyContent($content)
{
// только если на странице есть нужный шаблон куда подставлять
if (strpos( $content, '<ШАБЛОН>')!== false ) {
ob_start();
// здесь вызываются компоненты которые надо подставить.
$out1 = trim(ob_get_contents());
ob_end_clean();
$out1 = str_replace('<ШАБЛОН>', $out1, $content);
}
}
Замечание. <ШАБЛОН> лучше всего писать со спецсимволами <>.
Начинающие хакеры не испортят вид вашей страницы, написав что-то в отзыве о товаре.
Cпособ 2.1.
Примерно тоже самое, но пишем в коде страницы, на которой лежат компоненты:
ob_start();
// код компонента, куда вставляем.
$out1 = trim(ob_get_contents());
ob_end_clean();
if (strlen($out1)>0) {
if ( strpos( $out1, '<ШАБЛОН>')!== false ) {
ob_start();
// код, что вставляем.
$out2 = trim(ob_get_contents());
ob_end_clean();
echo str_replace('<ШАБЛОН>', $out2, $out1);
} else {
echo $out1;
}
}
Способ 2.2.
Чуть хитрее. Применяется, когда во вставляемом компоненте включен аякс.
Мы не вставляем один компонент в другой. А наоборот. Первый компонент режем и половинки вставляем вокруг второго.
ob_start();
// код компонента, куда вставляем.
$out1 = trim(ob_get_contents());
ob_end_clean();
if (strlen($out1)>0) {
if ( strpos( $out1, '<ШАБЛОН>')!== false ) {
$parts = explode('<ШАБЛОН>', $out1);
echo $parts[0];
// код, что вставляем.
echo $parts[1];
} else {
echo $out1;
}
}
Способ 3.
Самый любимый. В одну строчку.
А зачем парсить на сервере и тратить дорогие ресурсы? Пусть у пользователя JavaScript сам подставляет.
Оказалось, что такая реализация самая универсальная и совсем не сложная.
<!--Скрытый див, где-то на странице.-->
<div style="display: none;" id="from">Наш html, который надо подставить</div>
...
<!--пустой див в закэшированном компонете-->
<div style="display: block;" id="to"></div>
<script type="text/JavaScript">
<!--Вот эта строчка-->
document.getElementById('to').innerHTML = document.getElementById('from').innerHTML;
</script>
Мы всегда можем найти нужный узел по id и вставить в него тот HTML который нам нравится.
С точки зрения быстродействия, безопасности и простоты реализации во многих случаях третий способ — самый лучший выбор.
Зайцев Артемий, всегда думал что коммерческая CMS такого уровня должна предоставлять это из коробки. такие элементарные вещи уже решены даже в беслпатных системах
Группы на сайте создаются не только сотрудниками «1С-Битрикс», но и партнерами компании. Поэтому мнения участников групп могут не совпадать с позицией компании «1С-Битрикс».