+7 495 008 8452 пн.-пт. 10:00 – 17:00
Если у вас возникли какие либо вопросы которые вы не смогли решить по нашим публикациям самостоятельно,
то ждем ваше обращение в нашей службе тех поддержки.


Компонент в теле новости

Иногда стоит задача в теле новости вывести какой-то компонент. Например, опрос. И рассмотрим на примере его вывода.


1. Обозначим маркер для замены на текущий опрос. Пусть этот маркер будет #VOTE_ID_XX#, где XX это ID нужного нам опроса.

2. Настроим компонент (в нашем случае это bitrix:voting.current) на отдельной странице так как нам удобно. Отключим работу в AJAX-режиме.

3. Копируем шаблон новости в свой шаблон для редактирования. Открываем шаблон детального просмотра и создаем два файла: result_modifier.php и component_epilog.php

result_modifier.php такого содержания:
<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();?>
<?$this->__component->SetResultCacheKeys(array("CACHED_TPL"));?>


component_epilog.php такого:
<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();?>
<?
echo preg_replace_callback(
         "/#VOTE_ID_([\d]+)#/is".BX_UTF_PCRE_MODIFIER,
         create_function('$matches', 'ob_start();
         /*component here*/
         $retrunStr = @ob_get_contents();
         ob_get_clean();
         return $retrunStr;'),
         $arResult["CACHED_TPL"]);
?>


4. Вместо /*component here*/ сейчас вставим вызов нашего компонента (для большей наглядности не стал писать все в куче):

$GLOBALS["APPLICATION"]->IncludeComponent(
   "bitrix:voting.current",
   "main_page",
   Array(
      "CHANNEL_SID" => "ANKETA",
      "VOTE_ID" => $matches[1],
      "CACHE_TYPE"   =>   "A",
      "CACHE_TIME"   =>   "3600",
      "AJAX_MODE" => "N",
      "AJAX_OPTION_SHADOW" => "Y",
      "AJAX_OPTION_JUMP" => "Y",
      "AJAX_OPTION_STYLE" => "Y",
      "AJAX_OPTION_HISTORY" => "N",
   )
);


Обратите внимание, что вместо обычного $APPLICATION написано $GLOBALS["APPLICATION"]. Так надо для видимости объекта внутри временной функции. В остальном это полностью код того компонента, который мы взяли из тела страницы в п.2.

И обратите внимание на $matches[1]. Это единственный динамический параметр в вызываемом компоненте. Динамический в том плане, что он будет зависеть от того какой маркер мы меняем. Для #VOTE_ID_1# он будет равен 1, для #VOTE_ID_1# 2 и так далее.

5. Теперь надо изменить template.php. На второй строчке впишите конструкцию:
<?ob_start();?>

а в самом конце:
<?
$this->__component->arResult["CACHED_TPL"] = @ob_get_contents();
ob_get_clean();
?>


Манипуляции с component_epilog.php сделаны чтобы обойти кеширование. Скачать измененный шаблон с необходимыми файлами можно здесь.

Что получили в итоге:








Большое спасибо Сергею за поимку одного бага, а также подсказку более верного пути.

Комментарий от Антона Козлова:
если внутренним компонентом использовать компонент типа catalog.smart.filter, при ajax-запросе внутри компонента вывод будет неожиданным из-за использования $APPLICATION->RestartBuffer(); внутри выходного ajax.php. Причина в том, что $APPLICATION->RestartBuffer(); очищает только первый уровень буфера, а в Вашем примере некешируемый компонент находится внутри второго уровня буфера. Предложенное решение внести "while (ob_get_level())     ob_end_clean();" в рестарт буфера ТП не поддержали, просто ответив, что вложенная буферизация не поддерживается стандартными методами.


Назад в раздел

Подписаться на новые материалы раздела:














CAPTCHA