Иногда стоит задача в теле новости вывести какой-то компонент. Например, опрос. И рассмотрим на примере его вывода. [spoiler]
1. Обозначим маркер для замены на текущий опрос. Пусть этот маркер будет #VOTE_ID_XX#, где XX это ID нужного нам опроса.
2. Настроим компонент (в нашем случае это bitrix:voting.current) на отдельной странице так как нам удобно. Отключим работу в AJAX-режиме.
3. Копируем шаблон новости в свой шаблон для редактирования. Открываем шаблон детального просмотра и создаем два файла: result_modifier.php и component_epilog.php
Обратите внимание, что вместо обычного $APPLICATION написано $GLOBALS["APPLICATION"]. Так надо для видимости объекта внутри временной функции. В остальном это полностью код того компонента, который мы взяли из тела страницы в п.2.
И обратите внимание на $matches[1]. Это единственный динамический параметр в вызываемом компоненте. Динамический в том плане, что он будет зависеть от того какой маркер мы меняем. Для #VOTE_ID_1# он будет равен 1, для #VOTE_ID_1# 2 и так далее.
5. Теперь надо изменить template.php. На второй строчке впишите конструкцию:
если внутренним компонентом использовать компонент типа catalog.smart.filter, при ajax-запросе внутри компонента вывод будет неожиданным из-за использования $APPLICATION->RestartBuffer(); внутри выходного ajax.php. Причина в том, что $APPLICATION->RestartBuffer(); очищает только первый уровень буфера, а в Вашем примере некешируемый компонент находится внутри второго уровня буфера. Предложенное решение внести "while (ob_get_level()) ob_end_clean();" в рестарт буфера ТП не поддержали, просто ответив, что вложенная буферизация не поддерживается стандартными методами.
Свои пять копеек вставлю, можно? Я бы заменил в коде: $retrunStr = @ob_get_contents(); ob_get_clean(); просто на: $retrunStr = ob_get_clean();
Ну и это заменил бы: $this->__component->arResult["CACHED_TPL"] = @ob_get_contents(); ob_get_clean(); на: $component->arResult["CACHED_TPL"] = ob_get_clean();
А еще от result_modifier.php бы избавился (лишняя файловая операция все же), т.е. $component->SetResultCacheKeys(array("CACHED_TPL")); добавил бы прямо в template.php Здесь result_modifier.php, я так понимаю, был создан только для следования правилам написания кода битрикса.
Спасибо, как раз пригодится Только #VOTE_ID_2# как то не юзер-фрэндли. Было бы вообще клево, добавить кнопочку в редактор, но это уже под конкретную задачу естессно.
Подробнее про кнопочку можно посмотреть у Defa. Они там типограф прицепили. У нас парни в соседнем отделе по мотивам вашей статьи и их кнопочки как раз сейчас будут приделывать кнопку добавления видео в новости
Высшая крутотень - это модульная реализация решения, с выводом на панели инструментом кнопки, которая бы открывала окно с набором компонент (так как у нас отсутствует стандартное правое дерево компонент). И эти компоненты втыкаешь в тело новости, настраиваешь, все дела
Но это реально геморой, проще ограничиться частными случаями.
Если код написан правильно и в template.php нет исполняемого кода, то нет, не равносильно, но вот если template.php очень тяжелый, то парсер будет лишний раз напрягаться, вместо того чтобы просто выплюнуть кешированный шаблон. Так что такой подход должен быть осознанным (например, когда в теле надо вывести логин пользователя).
Да, тот вариант, что я привёл, требует кастомизации компонента. Просто как раз недавно делал показ страницы клуба, где от самого клуба (элемент инфоблока) нужны только заголовок и детальное описание, а на странице клуба нужно показать новости клуба, последние темы форума клуба, последние фотографии клуба, отзывы о клубе и блоги клуба. В таком случае, имхо, разумней не заморачиваться с ob_*, а тупо размещать вызов соответствующих компонент в самом шаблоне, вынеся шаблон за пределы кешируемой области.
Тогда это можно сделать и без использования ob_start() на любом стандартном компоненте, просто весь шаблон переносится в component_epilog.php, а в template.php добавляются нужные ключи для хранения в кэше.
если внутренним компонентом использовать компонент типа catalog.smart.filter, при ajax-запросе внутри компонента вывод будет неожиданным из-за использования $APPLICATION->RestartBuffer(); внутри выходного ajax.php. Причина в том, что $APPLICATION->RestartBuffer(); очищает только первый уровень буфера, а в Вашем примере некешируемый компонент находится внутри второго уровня буфера. Предложенное решение внести "while (ob_get_level()) ob_end_clean();" в рестарт буфера ТП не поддержали, просто ответив, что вложенная буферизация не поддерживается стандартными методами.
Группы на сайте создаются не только сотрудниками «1С-Битрикс», но и партнерами компании. Поэтому мнения участников групп могут не совпадать с позицией компании «1С-Битрикс».