Битрикс. Композитный сайт. Часть 3 из 3
27.11.2018
Теги: CMS • Web-разработка • Битрикс • Кеширование • КомпозитныйСайт • Настройка • ОтложенныеФункции
Класс FrameStatic
Класс FrameStatic
просто расставляет метки начала и конца динамической зоны. И потом, когда страница сформирована, по этим меткам вырезается контент динамической области.
<?php 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> <?php $randomElementsFrame = new \Bitrix\Main\Page\FrameStatic('random-elements-label'); // устанавливаем заглушку, которая будет показана на первом хите композита $randomElementsFrame->setStub('Загрузка...'); // начинаем буферизацию $randomElementsFrame->startDynamicArea(); // подключаем компонент, который формирует блок случайных элементов $APPLICATION->IncludeComponent( "tokmakov:iblock.random", "", array(/*...*/) ); // завершаем буферизацию $randomElementsFrame->finishDynamicArea(); ?> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore... </p> <?php require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php"); ?>
<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>
<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
контейнера от нуля до единицы после вставки динамического контента:
<?php 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> <div id="random-elements"> <?php $randomElementsFrame = new \Bitrix\Main\Page\FrameStatic('random-elements-label'); // задаем контейнер, внутри которого будет сначала пусто, а потом динамический контент $randomElementsFrame->setContainerID('random-elements'); // добавляем анимацию динамического контента после ajax-запроса; opacity плавно изменяется от 0 до 1 $randomElementsFrame->setAnimation(true); // начинаем буферизацию $randomElementsFrame->startDynamicArea(); // вызываем наш компонент, который формирует блок случайных элементов $APPLICATION->IncludeComponent( "tokmakov:iblock.random", "", array(/*...*/) ); // завершаем буферизацию $randomElementsFrame->finishDynamicArea(); ?> </div> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore... </p> <?php require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php"); ?>
#random-elements {
min-height: 242px;
background: url(../img/ajax-loader.gif) #fff no-repeat center center;
}
<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> </div>
<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()
в шаблоне.
$frame = new \Bitrix\Main\Page\FrameBuffered('some-dinamic-area'); // или вызов метода $this->createFrame() в шаблоне $frame->begin(); // динамический контент $frame->beginStub(); // html-код заглушки $frame->end();
Код между вызовами begin()…beginStub()
и beginStub()…end()
выполняется всегда. И на первом хите к странице (на котором создается кеш) и на ajax-хите. Эти методы занимаются буферизацией контента и не являются аналогами конструкции if…else
. Вызов $frame->end()
завершает разметку динамичной части.
FrameBuffered
, не забывайте, что отложенные функции работать не будут.
Давайте рассмотрим использование этого класса на примере компонента, который выводит на страницу случайные элементы инфоблока:
<?php 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> <?php $frame = new \Bitrix\Main\Page\FrameBuffered('random-elements-label'); $frame->begin(); // вызываем наш компонент, который формирует блок случайных элементов $APPLICATION->IncludeComponent( "tokmakov:iblock.random", "", array(/*...*/) ); $frame->beginStub(); ?> <section id="random-elements-stub"> <article></article> <article></article> <article></article> <article></article> </section> <?php $frame->end(); ?> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore... </p> <?php require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php"); ?>
Для заглушки зададим стили:
#random-elements-stub {
overflow: hidden;
margin: 15px 0;
background: #f5f5f5;
border: 1px solid #d1d1d1;
border-radius: 10px;
padding: 10px;
}
#random-elements-stub > article {
float: left;
width: 24%;
box-sizing: border-box;
border: 1px solid #d1d1d1;
padding: 10px;
border-radius: 10px;
background: #fff;
margin-right: 1.33333%;
min-height: 220px;
background: url(../img/ajax-loader.gif) #fff no-repeat center center;
}
#random-elements-stub > article:last-child {
margin-right: 0;
}
Страница, полученная из кеша (с заглушкой):
<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-запроса:
<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>
Вместо заключения
Как уже было отмечено ранее, по умолчанию компонент голосует за композит, а шаблон компонента — против. Мы можем изменить это поведение по-умолчанию, с помощью вызова метода setFrameMode()
в коде компонента и в коде шаблона. Например, для компонента «Случайные элементы инфоблока»
<?php /* * Файл local/components/tokmakov/iblock.random/component.php */ if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED!==true) die(); // компонент голосует против композита, его нельзя кешировать, // иначе мы не получим случайные элементы инфоблока $this->setFrameMode(false);
<?php /* * Файл local/components/tokmakov/iblock.random/templates/.default/template.php */ if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED!==true) die(); // шаблон компонента голосует против композита, его нельзя кешировать, // иначе мы не получим случайные элементы инфоблока $this->setFrameMode(false);
Теперь, если на какой-нибудь странице сайта мы подключим этот компонент, такая страница не попадет в кеш:
<?php 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> <?php // вызываем наш компонент, который формирует блок случайных элементов $APPLICATION->IncludeComponent( "tokmakov:iblock.random", "", array(/*...*/) ); ?> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore... </p> <?php require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php"); ?>
Чтобы страница с таким компонентом все-таки попала в кеш, можно запретить компоненту и шаблону голосовать «против» — считаем, что шаблон и компонент проголосовали «за»:
<?php 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> <?php $staticHTMLCache = \Bitrix\Main\Data\StaticHTMLCache::getInstance(); // запрещаем компоненту случайных элементов голосовать против композита $staticHTMLCache->disableVoting(); // вызываем наш компонент, который формирует блок случайных элементов $APPLICATION->IncludeComponent( /*...*/ ); // компоненты ниже будут голосовать за или против композита как обычно $staticHTMLCache->enableVoting(); ?> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore... </p> <?php require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php"); ?>
Теперь страница попадет в кеш, но будет постоянно перезаписываться на ajax-хите. Давайте вообще отменим ajax-запрос для этой страницы:
<?php require($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php"); $APPLICATION->SetTitle("Случайные элементы"); /* * Создаем кеш сроком хранения 60 секунд */ $composite = \Bitrix\Main\Page\Frame::getInstance(); $composite->setAutoUpdate(false); $composite->setAutoUpdateTTL(60); /* * Запрещаем всем компонентам ниже голосовать */ $staticHTMLCache = \Bitrix\Main\Data\StaticHTMLCache::getInstance(); $staticHTMLCache->disableVoting(); ?> <h1>Случайные элементы</h1> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore... </p> <?php // вызываем наш компонент, который формирует блок случайных элементов $APPLICATION->IncludeComponent( /*...*/ ); ?> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore... </p> <?php require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php"); ?>
Теперь страница просто кешируется и не выполняет ajax-запрос до тех пор, пока не истечет её время жизни — 60 секунд. Этот фоновый запрос перезапишет кеш — и у нас будет новый набор случайных элементов на следующие 60 секунд.
Поиск: CMS • Web-разработка • Битрикс • Кеширование • Композитный сайт • FrameStatic • setStub • startDynamicArea • finishDynamicArea • setContainerID • setAnimation • FrameBuffered • begin • beginStub • end • Отложенные функции • Frame • StaticHTMLCache