Отложенные функции
Отложенные функции — технология, позволяющая задавать заголовок страницы, пункты навигационной цепочки, CSS стили, дополнительные кнопки в панель управления, мета-теги и т.п. с помощью функций, используемых непосредственно в теле страницы. Соответствующие результаты работы этих функций выводятся в прологе, то есть выше по коду, чем они были заданы.
Технология была создана в первую очередь для использования в компонентах, которые, как правило, выводятся в теле страницы, но при этом внутри них могут быть заданы заголовок страницы, добавлен пункт в навигационную цепочку, добавлена кнопка в панель управления и так далее.
Технология была создана в первую очередь для использования в компонентах, которые, как правило, выводятся в теле страницы, но при этом внутри них могут быть заданы заголовок страницы, добавлен пункт в навигационную цепочку, добавлена кнопка в панель управления и так далее.
Примеры общих отложенных функций
Любой исходящий поток из PHP скрипта буферизируется. Как только в коде встречается одна из следующих функций:
Устанавливает заголовок страницы. Если заголовок страницы у вас выводится с помощью метода CMain::ShowTitle, то устанавливать его вы можете уже после того как у вас будет выведен пролог сайта, подробнее
index.php$APPLICATION->SetTitle("Главная страница");
возвращает заголовок страницы, подробнее.
index.php$APPLICATION->GetTitle()
Отображает заголовок страницы, позволяет задавать заголовок страницы например, внутри компонента после того как был выведен пролог сайта, подробнее
index.php// выводим заголовок окна браузера
<title><?php $APPLICATION->ShowTitle(); ?></title>
// выводим заголовок страницы
<h1><?php $APPLICATION->ShowTitle(false); ?></h1>
Выводит свойство страницы, учитывая свойства раздела. Свойства раздела могут хранится в файле .section.php соответствующего раздела сайта в массиве.
.section.php$arDirProperties = Array(
"property-new" => "<p>Кастомное свойство в .section.php</p>"
);
Свойства страницы чаше задаются, либо в теле страницы, либо между служебной частью и визуальной частью пролога. Свойства раздела автоматически наследуются всеми подразделами и страницами данного раздела, подробнее.
index.php$APPLICATION->SetPageProperty("property-new", "<p>Кастомное свойство в index.php</p>");
$APPLICATION->ShowProperty("property-new");
Возвращает свойство страницы, учитывая свойства раздела в файле .section.php, подробнее.
index.php$APPLICATION->SetPageProperty("property-new", "<p>Кастомное свойство</p>");
$APPLICATION->GetProperty("property-new");
Возвращает свойство страницы, подробнее.
Возвращает свойство раздела, подробнее.
Возвращает массив всех свойств страницы, подробнее.
Возвращает массив всех свойств раздела, подробнее.
Устанавливает свойство страницы, подробнее.
index.php$APPLICATION->SetPageProperty("property-new", "<p>Кастомное свойство</p>");
$APPLICATION->GetPageProperty("property-new");
Устанавливает свойство раздела, подробнее.
Отображает свойство страницы в виде мета-тега, подробнее.
Возвращает свойство раздела/страницы обрамленное тегом meta, подробнее.
Отображает CSS стили страницы, позволяет задавать стили страницы например, внутри компонента после того как был выведен пролог сайта, подробнее.
Отображает навигационную цепочку, позволяет задавать навигационную цепочку, внутри компонента после того как был выведен пролог сайта, подробнее.
Отображает панель управления в публичной части сайта, подробнее.
Как это работает
Весь буферизированный до этого контент запоминается в очередном элементе стека КонтентСтраницы. И сразу полсе этого в стек КонтентСтраницы добавляется пустой элемент. В дальнейшем этот пустой элемент будет заполнен результатом выполнения отложенной функции. Имя этой отложенной функции запоминается в стеке ОтложенныеФункции. Буфер очищается и буферизация снова включается.
Таким образом, существует стек КонтентСтраницы, в котором находится весь контент страницы, разбитый на части. В этом же стеке есть пустые элементы, предназначенные для их дальнейшего заполнения результатами отложенных функций. Также существует стек ОтложенныеФункции, в котором запоминаются имена и параметры отложенных функции в порядке их следования в коде.
В конце страницы, в служебной части эпилога, выполняются следующие действия:
- все отложенные функции из стека
ОтложенныеФункцииначинают выполняться одна за другой - результаты их выполнения вставляются в специально предназначенные для этого места в стек
КонтентСтраницы - весь контент из стека
КонтентСтраницы«склеивается» (конкатенируется) и выводится на экран
Таким образом, технология позволяет фрагментировать весь контент страницы, разбивая его на части с помощью специальных функций, обеспечивающих временное откладывание выполнения других функций. В конце страницы все отложенные функции выполняются одна за другой и результаты их выполнения вставляются в отведенные для этого места внутри фрагментированного контента страницы. Затем весь контент склеивается и отправляется браузеру посетителя сайта.
Пример использования с заголовками
Давайте рассмотрим пример установки заголовка страницы и заголовка окна браузера:
header.php<?
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();
?>
<!DOCTYPE html>
<html>
<head>
<title>
<?
// показываем заголовок браузера
$APPLICATION->ShowTitle();
?>
</title>
</head>
Поскольку мы нигде не вызываем методы SetTitle(), заголовок браузера и заголовок страницы у нас пустые. Давайте установим значения заголовков:
index.php<?
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php");
// устанавливаем заголовок страницы
$APPLICATION->SetTitle('Заголовок (старый)');
// устанавливаем заголовок браузера
$APPLICATION->SetPageProperty('title', 'Заголовок (старый)');
?>
<h1><?php $APPLICATION->ShowTitle(false); /* показываем заголовок страницы */ ?></h1>
<?
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php");
?>
Пример использования в компоненте, файл class.php
В компонентах Битрикс часто можно увидеть такой код, который устанавливает значения заголовков и значенния мета-тегов keywords и description:
class.php<?
if ($this->StartResultCache()) {
//****************//
// Код компонента //
//****************//
// получаем данные раздела SEO
$ipropElementValues = new \Bitrix\Iblock\InheritedProperty\ElementValues($arResult["IBLOCK_ID"], $arResult["ID"]);
$arResult["SEO"] = $ipropElementValues->getValues();
// кэш не затронет весь код ниже, он будут выполняться на каждом хите, здесь работаем с другим $arResult, будут доступны только те ключи массива, которые перечислены в вызове SetResultCacheKeys()
if (isset($arResult['ID'])) {
// ключи $arResult перечисленные при вызове этого метода, будут доступны в component_epilog.php и ниже по коду, обратите внимание там будет другой $arResult
$this->SetResultCacheKeys(
array(
'SEO'
)
);
$this->IncludeComponentTemplate();
} else { // что-то пошло не так
$this->AbortResultCache();
\Bitrix\Iblock\Component\Tools::process404(
trim($arParams['MESSAGE_404']) ?: 'Элемент инфоблока не найден',
true,
$arParams['SET_STATUS_404'] === 'Y',
$arParams['SHOW_404'] === 'Y',
$arParams['FILE_404']
);
}
}
// устанавливаем метатеги
if (isset($arResult['ID'])) {
// делаем $APPLICATION глобальной переменной
global $APPLICATION;
// устанавливаем заголовок окна браузера title
if (isset($arResult["SEO"]["ELEMENT_META_TITLE"]) && $arResult["SEO"]["ELEMENT_META_TITLE"] != "") {
$APPLICATION->SetTitle($arResult["SEO"]["ELEMENT_META_TITLE"]);
}
// устанавливаем заголовок страницы h1
if (isset($arResult["SEO"]["SECTION_PAGE_TITLE"]) && $arResult["SEO"]["SECTION_PAGE_TITLE"] != "") {
$APPLICATION->SetPageProperty("H1", $arResult["SEO"]["SECTION_PAGE_TITLE"]);
}
// устанавливаем мета-тег keywords
if (isset($arResult["SEO"]["ELEMENT_META_KEYWORDS"]) && $arResult["SEO"]["ELEMENT_META_KEYWORDS"] != "") {
$APPLICATION->SetPageProperty("keywords", $arResult["SEO"]["ELEMENT_META_KEYWORDS"]);
}
// устанавливаем мета-тег description
if (isset($arResult["SEO"]["ELEMENT_META_DESCRIPTION"]) && $arResult["SEO"]["ELEMENT_META_DESCRIPTION"] != "") {
$APPLICATION->SetPageProperty("description", $arResult["SEO"]["ELEMENT_META_DESCRIPTION"]);
}
}
Для вывода h1 в нужной части страницы:
<h1><? $APPLICATION->ShowTitle('H1') ?></h1>
Пример использования в шаблоне компонента, файл template.php
Метод вывода отложенных функций ShowViewContent() нельзя использовать в файлах шаблона компонента template.php, результаты выполнения этих файлов кешируются.
Методы ShowViewContent () и AddViewContent ()
Метод ShowViewContent() добавляет в стек пустой элемент. А метод AddViewContent() добавляет в этот элемент контент, который формируется ниже.
Пример с ob_start():
index.php<?
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php");
// здесь выводим контент с меткой «random-elements», который будет сфорирован ниже
$APPLICATION->ShowViewContent('random-elements');
// включаем буферизацию вывода, все идет в отдельный буфер
ob_start();
// вызываем компонент, который формирует список блок случайных элементов инфоблока
$GLOBALS['APPLICATION']->IncludeComponent(
"tokmakov:iblock.random",
"",
Array(
"ELEMENT_COUNT" => "4",
"ELEMENT_URL" => "#SITE_DIR#/#IBLOCK_CODE#/element/code/#ELEMENT_CODE#/",
"IBLOCK_ID" => "5",
"IBLOCK_TYPE" => "content"
)
);
// выключаем буферизацию и помечаем этот контент меткой «random-elements»
$APPLICATION->AddViewContent('random-elements', ob_get_clean());
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php");
?>
Пример с простым контентом:
index.php<?
// добавление контента
$APPLICATION->AddViewContent(
// название
'page_class',
// контент
'custom-page',
// приоритет вывода
100
);
// вывод в нужном месте
<div class="<?=$APPLICATION->ShowViewContent('page_class')?>"></div>
Методы SetViewTarget () и EndViewTarget ()
В шаблоне компонента можно использовать методы SetViewTarget() и EndViewTarget():
template.php<?
// включаем буферизацию и помечаем этот контент меткой smart-filter
$this->SetViewTarget('smart-filter');
?>
<div class="smart-filter">
<?
// подключаем компонент
$APPLICATION->IncludeComponent(
'bitrix:catalog.smart.filter',
'',
Array(
),
// обязательный параметр если вызывать компонент внутри другого компонента
$component
);
?>
</div>
<?
// выключаем буферизацию
$this->EndViewTarget();
?>
В том месте, где нам нужно вывести контент, добавляем в стек пустой элемент:
index.php<? $APPLICATION->ShowViewContent('smart-filter'); ?>
Использование в component_epilog.php
component_epilog.php<?
// инициализация шаблона
if(!$this->__template) {
$this->InitComponentTemplate();
}
// установка контента в буфер
$this->__template->SetViewTarget('content_id');
echo "Динамический контент: ".date('Y-m-d H:i:s');
$this->__template->EndViewTarget();
// вывод в нужном месте
<?$APPLICATION->ShowViewContent('content_id');?>