Twig — это обработчик шаблонов на PHP, распространяемый по лицензии BSD. Принцип его функционирования заключается в компиляции исходных темплейтов при первом обращении. Полученный код сохраняется в кэше (файлы с расширением .twig), и в дальнейшем используется каждый раз, когда осуществляется повторный вызов шаблона. Важной особенностью данного обработчика является то, что кэш шаблонов не связан с собственным кэшем cms Битрикс: если Twig кэширует непосредственно PHP-код, то сама система сохраняет HTML-разметку и результат работы компонента. Такой подход позволяет избегать конфликтов, а также исключает риск потери данных.
Еще одно преимущество Twig заключается в способе обновления записанных в кэше шаблонов. Кроме очевидной очистки каталога методом Twig_Environment::clearCacheFiles() , обработчик способен пересоздавать кэш конкретного шаблона в автоматическом режиме. Делать это можно посредством auto_reload, что актуально в процессе черновой разработки под движок Bitrix, а также используя опцию debug — она предоставляет возможность не только работать с кэшем в автоматическом режиме, но также использовать отладочные возможности.
Интеграция Twig в движок 1С Битрикс, как обычно, начинается с объявления глобальной переменной, отвечающей, собственно, за рендеринг шаблона. Затем ее необходимо зарегистрировать в глобальном массиве $arCustomTemplateEngines, указав расширение выходного файла. Выглядеть все это может следующим образом:
// Объявляем переменную function renderTwigTemplate($templateFile, $arResult, $arParams, $arLangMessages, $templateFolder, $parentTemplateFolder, $template) { echo TwigTemplateEngine::renderTemplate($templateFile, array( 'params' => $arParams, 'result' => $arResult, 'langMessages' => $arLangMessages, 'template' => $template, 'templateFolder' => $templateFolder, 'parentTemplateFolder' => $parentTemplateFolder, )); } // Регистрируем переменную в массиве global $arCustomTemplateEngines; $arCustomTemplateEngines["twig"] = array( "templateExt" => array("twig"), "function" => "renderTwigTemplate" ); |
Чего мы добились? Теперь, если в каталоге шаблона компонента Битрикс окажется файл с расширением .twig, будет вызываться функция renderTwigTemplate(). При этом, ей передается вся необходимая информация, включая параметры вызова и результат выполнения компонента, и даже языковые константы. Однако, здесь имеется подводный камень. Если в каталоге шаблона компонента cms Bitrix окажутся два файла example.twig и example.php, то приоритет отдается именно php-шаблону. То есть, реализовать подмену шаблонов, привязанную к типу активного в данный момент времени шаблонизатора (если таковых вы планируете использовать несколько), к сожалению, не выйдет.
После всех указанных действий, остается лишь настроить движок Twig. Для этого нужно подключить autoloader, указать путь к каталогу шаблонов и определить параметры конфигурации, а также добавить необходимые расширения. При этом придется использовать статичные свойства и методы класса. Данная особенность объясняется архитектурой cms 1С Битрикс — система не поддерживает размещение сервисных объектов.
// Инициализация и настройка Twig class TwigTemplateEngine { private static $twigEnvironment; public static function initialize($templateRootPath, $cacheStoragePath) { Twig_Autoloader::register(); $debugModeOptionValue = COption::GetOptionString ("htc.twigintegrationmodule", "debug_mode"); $debugMode = ($debugModeOptionValue == "Y") ? true : false; $loader = new Twig_Loader_Filesystem($templateRootPath); self::$twigEnvironment = new Twig_Environment($loader, array( 'autoescape' => false, 'cache' => $cacheStoragePath, 'debug' => $debugMode )); self::addExtensions(); global $arCustomTemplateEngines; $arCustomTemplateEngines["twig"] = array( "templateExt" => array("twig"), "function" => "renderTwigTemplate" ); } private static function addExtensions() { self::$twigEnvironment->addExtension(new Twig_Extension_Debug()); self::$twigEnvironment->addExtension(new BitrixTwigExtension()); } public static function renderTemplate($templateFile, array $context) { return self::$twigEnvironment->render($templateFile, $context); } public static function clearCacheFiles() { self::$twigEnvironment->clearCacheFiles(); } } |
Шаблонизатор подключен и настроен, казалось бы, можно начинать работу. Однако не все так просто — не обошлось без подводных камней и тут. Все проблемы решаемы, но отыскать их причину самостоятельно не так-то и просто, поэтому остановимся подробнее на ключевой тройке.
1. Система Bitrix устроена таким образом, что в ряде случаев приходится использовать глобальные объекты и специфические функции непосредственно в шаблонах компонентов. Нативной поддержки такого поведения Twig не имеет, однако обработчик позволяет создавать собственные расширения, в которых вы сможете указать все необходимые функции, теги, фильтры, и прочее. Естественно, разработка дополнительных расширений зависит от того, что именно вы хотите получить на выходе.
2. Вторая проблема возникает при передаче языковых констант в шаблон. Причина ошибки заключается, опять же, в специфике ядра cms. Как выяснилось, для успешной передачи констант языковой файл шаблона должен иметь такое же имя и расширение, как и сам шаблон (например, example.twig), и являться при этом PHP-файлом, как бы странно это ни звучало. Впрочем, вспоминая о конфликтах некоторых продуктов от 1С с патчами ядра, предотвращающими возникновение ошибки переполнения буфера, подобным мелочам перестаешь удивляться.
3. Еще один нюанс касается финального этапа рендернинга в cms 1С Bitrix. При использовании Twig-шаблонов component_epilog попросту не будет отрабатываться, а причина заключается в том, что автоматическое подключение происходит только к нативным шаблонам. Данная проблема решается принудительным вызовом component_epilog по завершении рендеринга — решение не самое изящное, зато действенное.
// Принудительный запуск component_epilog function renderTwigTemplate($templateFile, $arResult, $arParams, $arLangMessages, $templateFolder, $parentTemplateFolder, $template) { echo TwigTemplateEngine::renderTemplate($templateFile, array( 'params' => $arParams, 'result' => $arResult, 'langMessages' => $arLangMessages, 'template' => $template, 'templateFolder' => $templateFolder, 'parentTemplateFolder' => $parentTemplateFolder, )); $component_epilog = $templateFolder . "/component_epilog.php"; if(file_exists($_SERVER["DOCUMENT_ROOT"].$component_epilog)) { $component = $template->__component; $component->SetTemplateEpilog(array( "epilogFile" => $component_epilog, "templateName" => $template->__name, "templateFile" => $template->__file, "templateFolder" => $template->__folder, "templateData" => false, )); } } |
После описанных манипуляция мы получаем эффективное и полностью работоспособное решение. Twig будет адекватно взаимодействовать с движком 1С Битрикс для интернет магазина, корпоративного, промо, или любого другого сайта. Теперь будут преобразовываться нативные конструкции шаблонов в куда более наглядную и лаконичную форму, что значительно упрощает процесс разработки.