В качестве подопытного кролика мы используем один из самых популярных PHP шаблонизаторов - Twig. На синтаксисе и методах работы мы останавливаться не будем, так что настоятельно рекомендую ознакомиться с русскоязычной документацией.
Для нашего небольшого эксперимента нам потребуется веб-сервер с PHP на борту (я использую OpenServer), Composer в качестве пакетного менеджера и минимальные навыки работы в консоли.
Установка Composer тривиальна. Идем на сайт https://getcomposer.org/, переходим в раздел Download и следуем простым инструкциям. Для пользователей Windows все сводится к скачиванию и установке Composer-Setup.exe и последовательному копипасту четырех команд в консоль:
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"Для более удобной работы с Composer, я создам bat-файл:
php -r "if (hash_file('SHA384', 'composer-setup.php') === '55d6ead61b29c7bdee5cccfb50076874187bd9f21f65d8991d46ec5cc90518f447387fb9f76ebae1fbbacf329e583e30') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"
touch composer.bat…и помещу в него вызов composer.phar:
@php "%~dp0composer.phar" %*Теперь вместо длинной записи "php composer.phar" можно будет использовать сокращенную "composer".
Дальше нам необходимо задать некоторые настройки Composer. Дело в том, что по умолчанию, все пакеты зависимостей будут установлены в директорию /vendor. Мне это не нравится. Все дополнительные библиотеки я хочу видеть в папке /local/php_interface/lib/ и подключать их в init.php.
К счастью, пакетный менеджер позволяет легко это настроить. Создадим в корне сайта файл composer.json:
touch composer.jsonИ зададим нужную нам директорию таким вот образом:
{ "config": { "vendor-dir": "local/php_interface/lib" } }Теперь можно выполнить команду добавления зависимости Twig в проект и произвести установку:
composer require twig/twigГотово. После завершения установки в директории local/php_interface/lib/ должны появиться папки composer, twig и файл autoload.php.
Autoload.php необходимо подключить в init.php для работы всех установленных с помощью composer пакетов:
<?php if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/local/php_interface/lib/autoload.php')) require_once $_SERVER['DOCUMENT_ROOT'] . '/local/php_interface/lib/autoload.php';Теперь напишем обработчик. Для начала опишем в глобальной переменной $arCustomTemplateEngines список расширений и функцию-обработчик.
global $arCustomTemplateEngines; $arCustomTemplateEngines['twig'] = array( 'templateExt' => array( 'twig', ), 'function' => 'renderTwig' );Ну и опишем саму функцию-обработчик (в том же init.php). Функция принимает в себя все данные, с которыми работает шаблон. Из интересного тут: задание папки хранения кеша и его сброс при нажатии на Битриксовскую кнопку "Сбросить кеш". Остальное тривиально и описано в Basic API Usage на сайте Twig.
function renderTwig( $templateFile, $arResult, $arParams, $arLangMessages, $templateFolder, $parentTemplateFolder, $template ) { $loader = new Twig_Loader_Filesystem($_SERVER['DOCUMENT_ROOT']); $twig = new Twig_Environment($loader, array( 'cache' => '/bitrix/cache/twig/', 'auto_reload' => isset( $_GET[ 'clear_cache' ] ) && strtoupper($_GET[ 'clear_cache' ]) == 'Y', )); echo $twig->render( $templateFile, array( 'arResult' => $arResult, 'arParams' => $arParams, 'arLangMessages' => $arLangMessages, 'template' => $template, 'templateFolder' => $templateFolder, 'parentTemplateFolder' => $parentTemplateFolder, ) ); }Давайте начнем экспериментировать. Добавим на тестовую страницу компонент списка новостей и настроим на вывод какого-нибудь инфоблока:
<?require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/header.php')?> <?$APPLICATION->IncludeComponent( "bitrix:news.list", ".default", array( "COMPONENT_TEMPLATE" => ".default", "IBLOCK_TYPE" => "portfolio", "IBLOCK_ID" => "2", "NEWS_COUNT" => "10", "SORT_BY1" => "ACTIVE_FROM", "SORT_ORDER1" => "DESC", "SORT_BY2" => "SORT", "SORT_ORDER2" => "ASC", "FILTER_NAME" => "", "FIELD_CODE" => array( 0 => "", ), "PROPERTY_CODE" => array( 0 => "", ), "CHECK_DATES" => "Y", "DETAIL_URL" => "", "AJAX_MODE" => "N", "AJAX_OPTION_JUMP" => "N", "AJAX_OPTION_STYLE" => "Y", "AJAX_OPTION_HISTORY" => "N", "AJAX_OPTION_ADDITIONAL" => "", "CACHE_TYPE" => "A", "CACHE_TIME" => "36000000", "CACHE_FILTER" => "N", "CACHE_GROUPS" => "Y", "PREVIEW_TRUNCATE_LEN" => "", "ACTIVE_DATE_FORMAT" => "d.m.Y", "SET_TITLE" => "Y", "SET_BROWSER_TITLE" => "Y", "SET_META_KEYWORDS" => "Y", "SET_META_DESCRIPTION" => "Y", "SET_LAST_MODIFIED" => "N", "INCLUDE_IBLOCK_INTO_CHAIN" => "Y", "ADD_SECTIONS_CHAIN" => "Y", "HIDE_LINK_WHEN_NO_DETAIL" => "N", "PARENT_SECTION" => "", "PARENT_SECTION_CODE" => "", "INCLUDE_SUBSECTIONS" => "Y", "DISPLAY_DATE" => "Y", "DISPLAY_NAME" => "Y", "DISPLAY_PICTURE" => "Y", "DISPLAY_PREVIEW_TEXT" => "Y", "PAGER_TEMPLATE" => ".default", "DISPLAY_TOP_PAGER" => "N", "DISPLAY_BOTTOM_PAGER" => "Y", "PAGER_TITLE" => "Новости", "PAGER_SHOW_ALWAYS" => "N", "PAGER_DESC_NUMBERING" => "N", "PAGER_DESC_NUMBERING_CACHE_TIME" => "36000", "PAGER_SHOW_ALL" => "N", "PAGER_BASE_LINK_ENABLE" => "N", "SET_STATUS_404" => "N", "SHOW_404" => "N", "MESSAGE_404" => "" ), false ); ?> <?require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/footer.php')?>
Скопируем дефолтный шаблон и назовем его twig_test
Вот наша структура шаблона:
Смотрим, любуемся, а теперь берем и удаляем файл template.php. Вместо него создаем файл template.twig. Вот код файла template.twig целиком:
{% for item in arResult.ITEMS %} <div class="text_block"> <h2>< <a href="{{ item.DETAIL_PAGE_URL }}">{{ item.NAME }}</a> </h2> < img alt="{{ item.PREVIEW_PICTURE.ALT }}" src="{{ item.PREVIEW_PICTURE.SRC }}"> </div> {% endfor %}Судя по моим наблюдениям, twig с включенным кешированием не уступает в скорости шаблонам Bitrix с включенным композитом. Цифры примерно такие.
Шаблоны Bitrix + Кеш + Композит:
Twig + Кеш:
Как итог: шаблонизаторы в Bitrix использовать можно. Как минимум, это избавит разработчиков от вредной привычки получать данные в шаблоне компонента.