Bitrix доработка компонента облако тегов (search.tags.cloud)

Bitrix доработка компонента облако тегов (search.tags.cloud)

Относительно недавно перед нами встала задача реализации вывода популярных тегов элементов, задача вполне себе простая. Нам потребовалось вывести облако тегов для каждого из разделов, а когда мы не в разделе, то общее облако. Вот тут начинаются проблемы. Выяснилось, что если задать поле FILTER_NAME и передать туда дополнительные настройки фильтрации контента, то мы всегда будем видеть одно и тоже облако тегов, так как первый вывод для нас будет закеширован. Все дело в том, что ID кеша формируется следующим образом (файл /bitrix/components/bitrix/search.tags.cloud/component.php, строка №75):

...
if ($this->StartResultCache(false, array($USER->GetGroups())))
...

Из приведенного кода понятно, что ID файла кеша формируется только из групп пользователя, таким образом в секциях мы не будем наблюдать изменений в выводе шаблона. Решить данную проблему легко, есть несколько способов:

  1. В лоб - внести правки в код файла, но это путь разработчиков не читавших руководство и просто не правильно! Данный способ противопоказан к использованию, так как при обновлении Битрикса все изменения будут затерты и согласно правилам разработки - не рекомендовано вносить изменения в ядро проекта.
  2. Создание "компонента-обертки" - под этим понятием мы понимаем компонент принимающий такие же входные параметры, которые передаются в оригинальный компонент ядра.

Мы будем рассматривать только второй вариант. Задачи которые мы хотим возложить на компонент-обертку:

  1. Реализовать кеширование данных с учетом фильтра.
  2. Сохранить совместимость и удобство использования.

Для решения первой задачи в файле /bitrix/components/bxcert/search.tags.cloud.wrapper/component.php напишем следующий код:

global $USER;

if(strlen($arParams["FILTER_NAME"]) <= 0 || !preg_match("/^[A-Za-z_][A-Za-z01-9_]*$/", $arParams["FILTER_NAME"])) {
    $arFILTERCustom = array();
} else {
    $arFILTERCustom = $GLOBALS[$arParams["FILTER_NAME"]];
    if (!is_array($arFILTERCustom))
        $arFILTERCustom = array();
}

if ($this->StartResultCache(false, array($USER->GetGroups(), $arFILTERCustom))) {
    $arResult['PARAMS'] = $arParams;
    /**
     * Нам не надо чтобы оригинальный компонент bitrix:search.tags.cloud кешировался,
     * мы выносим кеширование на уровень выше - в компонент обертку.
     */
    $arResult['PARAMS']['CACHE_TYPE'] = 'N';
    $arResult['PARAMS']['CACHE_TIME'] = '0';
    $this->IncludeComponentTemplate();
}

Мы получаем пользовательский фильтр и кешируем результат с ним. Передаем в шаблон все исходные параметры за исключением настройки времени кеша и типа - в самом компоненте bitrix:search.tags.cloud теперь ничего кешировать не надо.

В шаблоне вызываем компонент следующим образом:

if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die();
$APPLICATION->IncludeComponent("bitrix:search.tags.cloud", "", $arResult['PARAMS'], $component);

Теперь можно вызывать компонент bxcert:search.tags.cloud.wrapper и передавать фильтр для ограничения выборки тегов с каждым пользовательским фильтром будет создан отдельный кеш. Вы можете скачать готовый компонент bxcert:search.tags.cloud.wrapper с нашего портала.

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

 2160 Bitrix, Битрикс, Разработка, Компонент, BXCert, bxcert:search.tags.cloud.wrapper
6 мая 2015
Команда BXCert

Наша команда разрабатывает портал BXCert, а также занимается разработкой сайтов на CMS 1С-Битрикс. Все участники являются сертифицированными специалистами Bitrix.

Возможно Вам будет интересно

Комментарии

Александр Голубев 30 марта 2016 в 20:59 / # / Ответить
добрый вечер!
хочу поблагодарить за этот замечательный компонент. сразу видно что у людей руки откуда надо растут и голова работает.
я видимо не из их числа :):):) как правильно передать section id, чтобы в фотогалерее (в альбоме) выходили теги из того альбома, в котором мы находимся?
еще раз огромное спасибо
Команда BXCert 05 апреля 2016 в 20:40 / # / Ответить
Скорее всего передать как-то так {$_REQUEST['SECTION_ID']}, т.е. когда в url будет передаваться не что подобное /gallery/10/, то в переменной $_REQUEST['SECTION_ID'] будет ID. Для полноты картины, конечно бы лучше код посмотреть.
Чтобы оставлять комментарии необходимо зарегистрироваться и пройти авторизацию.