Динамические зоны в шаблоне сайта
Как уже упоминалось выше, чтобы страница сайта попала в кеш, за композит должны проголосовать все компоненты, в том числе и те, которые подключаются в шаблонах сайта. Давайте на какой-нибудь странице подключим компонент, который выводит на странице несколько случайных элементов инфоблока. Такой компонент всегда голосует против композита, иначе мы не получим случайные элементы:
<?
/*
* Файл component.php
*/
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED!==true) die();
// компонент голосует против композита, его нельзя кешировать, иначе мы не получим случайные элементы инфоблока
$this->setFrameMode(false);
<?
/*
* Файл template.php
*/
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED!==true) die();
// шаблон компонента голосует против композита, его нельзя кешировать, иначе мы не получим случайные элементы инфоблока
$this->setFrameMode(false);
Но если подключение такого компонента происходит в шаблоне сайта, то все страницы, использующие этот шаблон, не смогут работать в композитном режиме.
<?
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php");
$APPLICATION->SetTitle("Случайные элементы");
?>
<h1>Случайные элементы</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore...
</p>
<?
// подключаем компонент, который формирует блок случайных элементов
$APPLICATION->IncludeComponent(
"hmarketing:iblock.random",
"",
array(
"ELEMENT_COUNT" => "4",
"ELEMENT_URL" => "#SITE_DIR#/#IBLOCK_CODE#/element/code/#ELEMENT_CODE#/",
"IBLOCK_ID" => "5",
"IBLOCK_TYPE" => "content"
)
);
?>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore...
</p>
<?
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php");
?>
Для простоты, я подключил компонент в рабочей области #WORK_AREA#
, но подключение такого компонента
может потребоваться и в файлах шаблонов сайта header.php
и footer.php
.
Чтобы все-таки заставить такие страницы работать в композитном режиме, предназначены классы FrameStatic
и FrameBuffered
. Так же, как и в шаблоне компонента, мы расставляем отметки в html-коде, где будет
начало и конец динамического контента. Или, сообщаем системе идентификатор контейнера с динамичеким контентом.
- Класс
FrameStatic
просто расставляет метки начала и конца динамической зоны. И потом, когда страница сформирована, по этим меткам вырезается контент динамической области - Класс
FrameBuffered
мы уже использовали, когда адаптировали шаблон компонента для работы в композитном режиме. Именно объект этого класса создаётся при вызове метода$this->createFrame()
в шаблоне компонента
Класс FrameStatic
Класс FrameStatic
просто расставляет метки начала и конца динамической зоны. И потом, когда страница
сформирована, по этим меткам вырезается контент динамической области.
<?
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php");
$APPLICATION->SetTitle("Случайные элементы");
?>
<h1>Случайные элементы</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore...</p>
<?
$randomElementsFrame = new \Bitrix\Main\Page\FrameStatic('random-elements-label');
// устанавливаем заглушку, которая будет показана на первом хите композита
$randomElementsFrame->setStub('Загрузка...');
// начинаем буферизацию
$randomElementsFrame->startDynamicArea();
// подключаем компонент, который формирует блок случайных элементов
$APPLICATION->IncludeComponent(
"hmarketing:iblock.random",
"",
array(/*...*/)
);
// завершаем буферизацию
$randomElementsFrame->finishDynamicArea();
?>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore...</p>
<?
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php");
?>
Временная заглушка до получения данных ajax-запросом:
<h1>Случайные элементы</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore...</p>
<div id="bxdynamic_random-elements-label_start" style="display:none"></div>
Загрузка...
<div id="bxdynamic_random-elements-label_end" style="display:none"></div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore...</p>
После ajax-запроса, на место заглушки будет вставлен html код:
<h1>Случайные элементы</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore...</p>
<div id="bxdynamic_random-elements-label_start" style="display:none"></div>
<section id="iblock-random-items">
<article>
<a href="/articles/element/code/dalmatin/">
<img src="/upload/iblock/c96/c9661e9c9cae4c7bca190da9289b8fbc.jpg" alt="Далматин. Породы собак" title="Далматин. Породы собак" title="Далматин. Породы собак" title="Далматин. Породы собак" />
</a>
<h4><a href="/articles/element/code/dalmatin/">Далматин</a></h4>
<p>Просмотров: 0</p>
</article>
<article>..........</article>
<article>..........</article>
<article>..........</article>
</section>
<div id="bxdynamic_random-elements-label_end" style="display:none"></div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore...</p>
Все бы ничего, но после ajax-запроса, когда на страницу вместо заглушки вставляется динамический контент, элементы
страницы «прыгают», что выглядит не очень красиво. Давайте это исправим — добавим свой контейнер для динамического
контента, зададим для него min-height
и ajax-loader.gif
в качестве
background-image
. И используем вызов метода setAnimation()
, который плавно изменяет
opacity
контейнера от нуля до единицы после вставки динамического контента:
<?
require($_SERVER["DOCUMENT_ROOT"] . "/bitrix/header.php");
$APPLICATION->SetTitle("Тест");
?>
<div id="random-elements">
<?
$randomElementsFrame = new \Bitrix\Main\Page\FrameStatic('random-elements-label');
// задаем контейнер, внутри которого будет сначала пусто, а потом динамический контент
$randomElementsFrame->setContainerID('random-elements');
// добавляем анимацию динамического контента после ajax-запроса; opacity плавно изменяется от 0 до 1
$randomElementsFrame->setAnimation(true);
// начинаем буферизацию
$randomElementsFrame->startDynamicArea();
// вызываем наш компонент, который формирует блок случайных элементов
$APPLICATION->IncludeComponent(
"hmarketing:iblock.random",
"",
array(/*...*/)
);
// завершаем буферизацию
$randomElementsFrame->finishDynamicArea();
?>
</div>
<? require($_SERVER["DOCUMENT_ROOT"] . "/bitrix/footer.php"); ?>
#random-elements {
min-height: 500px;
background-color: #000;
}
Временная заглушка до получения данных ajax-запросом:
<h1>Случайные элементы</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
dolore...</p>
<div id="random-elements"></div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
dolore...</p>
После ajax-запроса, на место заглушки будет вставлен html код:
<h1>Случайные элементы</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore...</p>
<div id="random-elements">
<section id="iblock-random-items">
<article>
<a href="/articles/element/code/abissinskaya-koshka/">
<img src="/upload/iblock/2cb/2cba6cc8ba68c914852b9c5b2f95b387.jpg" alt="Абиссинская кошка. Породы кошек. Статьи о домашних животных" title="Абиссинская кошка. Породы кошек. Статьи о домашних животных" />
</a>
<h4><a href="/articles/element/code/abissinskaya-koshka/">Абиссинская кошка</a></h4>
<p>Просмотров: 8</p>
</article>
<article>..........</article>
<article>..........</article>
<article>..........</article>
</section>
</div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore...</p>
Класс FrameBuffered
Этот класс мы уже использовали, когда адаптировали шаблон компонента для работы в композитном режиме. Именно объект
этого класса создаётся при вызове метода $this->createFrame()
в шаблоне.
// подобно вызовы метода $this->createFrame() в шаблоне
$frame = new \Bitrix\Main\Page\FrameBuffered('some-dinamic-area');
$frame->begin();
// динамический контент
$frame->beginStub();
// html-код заглушки
$frame->end();
Код между вызовами begin()…beginStub()
и beginStub()…end()
выполняется всегда. И на первом
хите к странице (на котором создается кеш) и на ajax-хите. Эти методы занимаются буферизацией контента и не являются
аналогами конструкции if…else
. Вызов $frame->end()
завершает разметку динамичной части.
При использовании класса FrameBuffered
, не забывайте, что отложенные функции работать не будут.
Давайте рассмотрим использование этого класса на примере компонента, который выводит на страницу случайные элементы инфоблока:
<?
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php");
$APPLICATION->SetTitle("Случайные элементы");
?>
<h1>Случайные элементы</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore...</p>
<?
$frame = new \Bitrix\Main\Page\FrameBuffered('random-elements-label');
$frame->begin();
// вызываем наш компонент, который формирует блок случайных элементов
$APPLICATION->IncludeComponent(
"hmarketing:iblock.random",
"",
array(/*...*/)
);
$frame->beginStub();
?>
<section id="random-elements-stub">
<article></article>
<article></article>
<article></article>
<article></article>
</section>
<? $frame->end(); ?>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore...</p>
<? require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php"); ?>
Временная заглушка до получения данных ajax-запросом:
<h1>Случайные элементы</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
dolore...</p>
<div id="bxdynamic_random-elements-label_start" style="display:none"></div>
<section id="random-elements-stub">
<article></article>
<article></article>
<article></article>
<article></article>
</section>
<div id="bxdynamic_random-elements-label_end" style="display:none"></div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
dolore...</p>
После ajax-запроса, на место заглушки будет вставлен html код:
<h1>Случайные элементы</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore...</p>
<div id="bxdynamic_random-elements-label_start" style="display:none"></div>
<section id="iblock-random-items">
<article>
<a href="/articles/element/code/labrador/">
<img src="/upload/iblock/89e/89ec16065d8ddd149ac22001916f9f67.jpg" alt="Лабрадор. Служебные породы. Статьи о домашних животных" title="Лабрадор. Служебные породы. Статьи о домашних животных" />
</a>
<h4><a href="/articles/element/code/labrador/">Лабрадор</a></h4>
<p>Просмотров: 0</p>
</article>
<article>..........</article>
<article>..........</article>
<article>..........</article>
</section>
<div id="bxdynamic_random-elements-label_end" style="display:none"></div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore...</p>