Устанавливаем Twig 3.* в Bitrix
Первым делом устанавливаем и подключаем composer в 1C-Bitrix.
Далее, для установки twig 3.*, переходим в /local/php_interface и в консоли выполняем команду
$ composer require twig/twig
Документация twig
После того как шаблонизатор Twig установлен, его нужно инициализировать.
Создаем файл /local/php_interface/include/twig.php, и прописываем в нем
<?php namespace Vik { use \Bitrix\Main\Loader; use Bitrix\Main\Config\Option; IncludeModuleLangFile(__FILE__); class Twig { private static $twigEnvironment; public static function initialize($documentRoot = '', $cachePath = '/bitrix/cache/twig') { if (empty($documentRoot)) return false; $cachePath = $documentRoot . $cachePath; //собираем шаблонизатор $loader = new \Twig\Loader\FilesystemLoader($_SERVER["DOCUMENT_ROOT"]); self::$twigEnvironment = new \Twig\Environment($loader, array( 'auto_reload' => true, 'autoescape' => false, 'cache' => $cachePath, 'debug' => false)); //печатаем массив на странице self::$twigEnvironment->addExtension(new \Vik\Twig\Debug()); //подключаем функции self::$twigEnvironment->addExtension(new \Vik\Twig\Bitrix()); //пользовательские функции if (file_exists($_SERVER["DOCUMENT_ROOT"] . '/local/php_interface/twigCustomFunctions.php') || file_exists($_SERVER["DOCUMENT_ROOT"] . '/bitrix/php_interface/twigCustomFunctions.php')) { self::$twigEnvironment->addExtension(new \Vik\Twig\TwigCustomFunctions()); } //подключаем обработчик шаблонизатора к битриксу $GLOBALS['arCustomTemplateEngines']['twig'] = [ 'templateExt' => ['twig', 'html.twig'], 'function' => 'TwigEngine' ]; } public static function renderTemplate($templateFile, $context = []) { return self::$twigEnvironment->render($templateFile, $context); } public static function clearCacheFiles() { self::$twigEnvironment->clearCacheFiles(); } } } namespace { function TwigEngine($templateFile, $arResult, $arParams, $arLangMessages, $templateFolder, $parentTemplateFolder, $template) { print \Vik\Twig::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, )); } } }
Создаем файл /local/php_interface/include/debug.php, и прописываем в нем
<?php namespace Vik\Twig { use Twig\TwigFunction; final class Debug extends \Twig\Extension\AbstractExtension { public function getFunctions(): array { // dump is safe if var_dump is overridden by xdebug $isDumpOutputHtmlSafe = \extension_loaded('xdebug') // false means that it was not set (and the default is on) or it explicitly enabled && (false === ini_get('xdebug.overload_var_dump') || ini_get('xdebug.overload_var_dump')) // false means that it was not set (and the default is on) or it explicitly enabled // xdebug.overload_var_dump produces HTML only when html_errors is also enabled && (false === ini_get('html_errors') || ini_get('html_errors')) || 'cli' === \PHP_SAPI; return [ new TwigFunction('dump', 'vik_twig_debug', ['is_safe' => $isDumpOutputHtmlSafe ? ['html'] : [], 'needs_context' => true, 'needs_environment' => true, 'is_variadic' => true]), new TwigFunction('adump', 'vik_twig_debug_admin', ['is_safe' => $isDumpOutputHtmlSafe ? ['html'] : [], 'needs_context' => true, 'needs_environment' => true, 'is_variadic' => true]), ]; } } } namespace { use Bitrix\Main\Context; use Twig\Environment; use Twig\Template; use Twig\TemplateWrapper; use Vik\Api\VApi; use Vik\Other\Dump; function vik_twig_debug(Environment $env, $context, ...$vars) { if (!$env->isDebug()) { return; } ob_start(); if (!$vars) { $vars = []; foreach ($context as $key => $value) { if (!$value instanceof Template && !$value instanceof TemplateWrapper) { $vars[$key] = $value; } } dump($vars); } else { dump(...$vars); } return ob_get_clean(); } function vik_twig_debug_admin(Environment $env, $context, ...$vars) { if (!$env->isDebug()) { return; } ob_start(); $status = false; if (VApi::isAdmin()) $status = true; $request = \Bitrix\Main\Context::getCurrent()->getRequest(); if ($request->get("all") !== null) $status = true; if ($status) { if (!$vars) { $vars = []; foreach ($context as $key => $value) { if (!$value instanceof Template && !$value instanceof TemplateWrapper) { $vars[$key] = $value; } } dump($vars); } else { dump(...$vars); } } return ob_get_clean(); } }
Создаем файл /local/php_interface/include/bitrix.php, и прописываем в нем
<?php namespace Vik\Twig { use Bitrix\Main\Localization\Loc; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; use Twig\TwigFunction; use CBitrixComponent; use CMain; final class Bitrix extends AbstractExtension implements GlobalsInterface { const DEFAULT_TEMPLATE_PATH = "/bitrix/templates/.default"; public function getName() { return 'bitrix'; } public function getGlobals(): array { return [ 'APPLICATION' => $GLOBALS['APPLICATION'], 'LANG' => LANG, 'POST_FORM_ACTION_URI' => POST_FORM_ACTION_URI, 'SITE_SERVER_NAME' => SITE_SERVER_NAME, 'SITE_TEMPLATE_PATH' => SITE_TEMPLATE_PATH, 'DEFAULT_TEMPLATE_PATH' => self::DEFAULT_TEMPLATE_PATH, '_REQUEST' => $_REQUEST, '_SESSION' => $_SESSION, '_COOKIE' => $_COOKIE, '_SERVER' => $_SERVER, ]; } public function getFilters() { return parent::getFilters(); // TODO: Change the autogenerated stub } public function getFunctions(): array { return [ new TwigFunction('isUser', 'vik_twig_isUser'), new TwigFunction('isAdmin', 'vik_twig_isAdmin'), new TwigFunction('bitrix_sessid_post', 'vik_twig_bitrix_sessid_post', ['str']), new TwigFunction('bitrix_sessid_get', 'vik_twig_bitrix_sessid_get', ['str']), new TwigFunction('showNote', 'vik_twig_showNote', ['message', 'css_class']), new TwigFunction('showError', 'vik_twig_showError', ['message', 'css_class']), new TwigFunction('showMessage', 'vik_twig_showMessage', ['message']), new TwigFunction('getMessage', '\Bitrix\Main\Localization\Loc::getMessage'), new TwigFunction('showComponent', [$this, 'showComponent']) ]; } public function showComponent($name, $template = '', $params = [], CBitrixComponent $parentComponent = null, $functionParams = [], $returnResult = false) { $app = new CMain(); $app->IncludeComponent($name, $template, $params, $parentComponent, $functionParams, $returnResult); } } } namespace { use Bitrix\Main\Localization\Loc; /** * Проверяем является ли пользователь администратором * * @return mixed */ function vik_twig_isAdmin() { return $GLOBALS['USER']->IsAuthorized(); } /** * Проверяем является ли пользователь авторизованным * * @return mixed */ function vik_twig_isUser() { return $GLOBALS['USER']->IsAdmin(); } /** * Сессия post * * @param string $str * @return int|string */ function vik_twig_bitrix_sessid_post($str = '') { if (!empty($str)) return bitrix_sessid_post($str); return bitrix_sessid_post(); } /** * Сессия get * * @param string $str * @return int|string */ function vik_twig_bitrix_sessid_get($str = '') { if (!empty($str)) return bitrix_sessid_get($str); return bitrix_sessid_get(); } /** * @param null $message * @param string $css_class * @return bool */ function vik_twig_showNote($message = null, $css_class = 'notetext') { if (empty($message)) return false; ShowError($message, $css_class); } /** * @param null $message * @param string $css_class * @return bool */ function vik_twig_showError($message = null, $css_class = 'errortext') { if (empty($message)) return false; ShowNote($message, $css_class); } /** * @param null $message * @return bool */ function vik_twig_showMessage($message) { if (empty($message)) return false; ShowMessage($message); } }
В /local/init.php подключаем наши классы, и инициализируем twig.
//подключаем классы \CModule::AddAutoloadClasses('', [ '\Vik\Twig' => '/local/php_interface/include/twig.php', '\Vik\Twig\Debug' => '/local/php_interface/include/debug.php', '\Vik\Twig\Bitrix' => '/local/php_interface/include/bitrix.php', ]); //подключаем шаблонизатор \Vik\Twig::initialize($_SERVER['DOCUMENT_ROOT'], '/bitrix/cache/twig');