Полный цикл в digital

Отложенные функции

Отложенные функции — технология, позволяющая задавать заголовок страницы, пункты навигационной цепочки, CSS стили, дополнительные кнопки в панель управления, мета-теги и т.п. с помощью функций, используемых непосредственно в теле страницы. Соответствующие результаты работы этих функций выводятся в прологе, то есть выше по коду, чем они были заданы.

Технология была создана в первую очередь для использования в компонентах, которые, как правило, выводятся в теле страницы, но при этом внутри них могут быть заданы заголовок страницы, добавлен пункт в навигационную цепочку, добавлена кнопка в панель управления и так далее.

Отложенные функции нельзя использовать в файлах шаблона компонента template.php и result_modifier.php, результаты выполнения этих файлов кешируются.

Алгоритм работы

Любой исходящий поток из PHP скрипта буферизируется. Как только в коде встречается одна из следующих функций:

  • CMain::ShowTitle()
  • CMain::ShowCSS()
  • CMain::ShowNavChain()
  • CMain::ShowProperty()
  • CMain::ShowMeta()
  • CMain::ShowPanel()

Весь буферизированный до этого контент запоминается в очередном элементе стека КонтентСтраницы. И сразу полсе этого в стек КонтентСтраницы добавляется пустой элемент. В дальнейшем этот пустой элемент будет заполнен результатом выполнения отложенной функции. Имя этой отложенной функции запоминается в стеке ОтложенныеФункции. Буфер очищается и буферизация снова включается.

Таким образом, существует стек КонтентСтраницы, в котором находится весь контент страницы, разбитый на части. В этом же стеке есть пустые элементы, предназначенные для их дальнейшего заполнения результатами отложенных функций. Также существует стек ОтложенныеФункции, в котором запоминаются имена и параметры отложенных функции в порядке их следования в коде.

В конце страницы, в служебной части эпилога, выполняются следующие действия:

  1. все отложенные функции из стека ОтложенныеФункции начинают выполняться одна за другой
  2. результаты их выполнения вставляются в специально предназначенные для этого места в стек КонтентСтраницы
  3. весь контент из стека КонтентСтраницы «склеивается» (конкатенируется) и выводится на экран

Таким образом, технология позволяет фрагментировать весь контент страницы, разбивая его на части с помощью специальных функций, обеспечивающих временное откладывание выполнения других функций. В конце страницы все отложенные функции выполняются одна за другой и результаты их выполнения вставляются в отведенные для этого места внутри фрагментированного контента страницы. Затем весь контент склеивается и отправляется браузеру посетителя сайта.

Пример использования с заголовками

Давайте рассмотрим пример установки заголовка страницы и заголовка окна браузера:

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>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore...
</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore...
</p>
<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");
?>

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

В компонентах Битрикс часто можно увидеть такой код, который устанавливает значения заголовков и значенния мета-тегов 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>

Пример использования в шаблоне компонента

В шаблоне компонента можно использовать методы 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'); ?>
Заполните форму уже сегодня!
Для начала сотрудничества необходимо заполнить заявку или заказать обратный звонок. В ответ получите коммерческое предложение, которое будет содержать индивидуальную стратегию с учетом требований и поставленных задач
Работаем по будням с 9:00 до 18:00. Заявки, отправленные в выходные, обрабатываем в первый рабочий день до 12:00.
Спасибо, ваш запрос принят и будет обработан!
Эйч Маркетинг