[I] "код_шаблонизатора" => array( "templateExt" => array("расширение1"[, "расширение2"...]), "function" => "имя_функции_подключения_движка" )[/I] |
где "код_шаблонизатора" - произвольное уникальное в рамках сайта слово,
"расширениеN" - расширение файла, который должен обрабатываться этим движком шаблонизации,
"имя_функции_подключения_движка" - имя функции, которая будет вызываться, если шаблон компонента имеет указанное расширение. Функцию можно разместить в этом же файле /bitrix/php_interface/init.php.
[spoiler]
Например, если на сайте кроме стандартного движка шаблонизации (PHP) требуется использовать Smarty, то в файл /bitrix/php_interface/init.php необходимо добавить следующий код
global $arCustomTemplateEngines; $arCustomTemplateEngines = array( "smarty" => array( "templateExt" => array("tpl"), "function" => "SmartyEngine" ), ); |
Тогда при подключении шаблона с расширением tpl будет запускаться не стандартный движок PHP, а функция SmartyEngine, которая должна подключить движок Smarty.
Синтаксис функций подключения движков следующий
function имя_функции_подключения_движка($templateFile, $arResult, $arParams, $arLangMessages, $templateFolder, $parentTemplateFolder, $template) |
где
$templateFile – путь к файлу шаблона относительно корня сайта,
$arResult – массив результатов работы компонента,
$arParams – массив входных параметров компонента,
$arLangMessages – массив языковых сообщений (переводов) шаблона,
$templateFolder – путь к папке шаблона относительно корня сайта (если шаблон лежит не в
папке, то эта переменная пуста),
$parentTemplateFolder - путь относительно корня сайта к папке шаблона комплексного
компонента, в составе которого подключается данный компонент (если компонент
подключается самостоятельно, то эта переменная пуста),
$template – объект шаблона.
Код функции подключения движка шаблонизации зависит от подключаемого движка.
Полный пример подключения движка Smarty
В файл /bitrix/php_interface/init.php необходимо добавить код
global $arCustomTemplateEngines; $arCustomTemplateEngines = array( "smarty" => array( "templateExt" => array("tpl"), "function" => "SmartyEngine" ) ); function SmartyEngine($templateFile, $arResult, $arParams, $arLangMessages, $templateFolder, $parentTemplateFolder, $template) { if (!defined("SMARTY_DIR")) define("SMARTY_DIR", "<абсолютный путь к движку Smarty>/libs/"); require_once('<абсолютный путь к движку Smarty>/libs/Smarty.class.php'); $smarty = new Smarty; $smarty->compile_dir = "<абсолютный путь к движку Smarty>/templates_c/"; $smarty->config_dir = "<абсолютный путь к движку Smarty>/configs/"; $smarty->template_dir = "<абсолютный путь к движку Smarty>/templates/"; $smarty->cache_dir = "<абсолютный путь к движку Smarty>/cache/"; $smarty->compile_check = true; $smarty->debugging = false; $smarty->assign("arResult", $arResult); $smarty->assign("arParams", $arParams); $smarty->assign("MESS", $arLangMessages); $smarty->assign("templateFolder", $templateFolder); $smarty->assign("parentTemplateFolder", $parentTemplateFolder); $smarty->display($_SERVER["DOCUMENT_ROOT"].$templateFile); } |
Строку "<абсолютный путь к движку Smarty>" нужно везде заменить на абсолютный путь к движку Smarty. Подробности по установке Smarty на сайт есть в системе помощи по Smarty.
Здесь в массиве $arCustomTemplateEngines регистрируется движок Smarty. В функции SmartyEngine инициализируются параметры движка в соответствии с требованиями Smarty (см. систему помощи Smarty). Далее в Smarty передаются переменные результатов работы компонента, входных параметров, языковых сообщений и т.д. И в конце вызывается метод обработки и показа шаблона Smarty.
Полный пример подключения движка XML/XSLT
global $arCustomTemplateEngines; $arCustomTemplateEngines = array( "xslt" => array( "templateExt" => array("xsl"), "function" => "XSLTEngine" ), ); function CreateXMLFromArray($xDoc, $xNode, $ar) { foreach($ar as $key=>$val) { if(!is_string($key) || strlen($key)<=0) $key = "value"; $xElement = $xDoc->createElement($key); if(is_array($val)) { CreateXMLFromArray($xDoc, $xElement, $val); } else { $xElement->appendChild($xDoc->createTextNode(iconv(SITE_CHARSET, "utf-8", $val))); } $xNode->appendChild($xElement); } return $xNode; } function XSLTEngine($templateFile, $arResult, $arParams, $arLangMessages, $templateFolder, $parentTemplateFolder, $template) { $arResult["PARAMS"] = array( "templateFolder" => $templateFolder, "parentTemplateFolder" => $parentTemplateFolder, "arParams" => $arParams, "arLangMessages" => $arLangMessages ); $xDoc = new DOMDocument("1.0", SITE_CHARSET); $xRoot = $xDoc->createElement('result'); CreateXMLFromArray($xDoc, $xRoot, $arResult); $xDoc->appendChild($xRoot); $xXsl = new DOMDocument(); $xXsl->load($_SERVER["DOCUMENT_ROOT"].$templateFile); $xProc = new XSLTProcessor; $xProc->importStyleSheet($xXsl); echo $xProc->transformToXML($xDoc); } |
Между тем выполнить Perl скрипт из функции подключения движка шаблонизации вполне можно:
Вопрос будет в передаче параметров Perl скрипту. Массив результатов работы компонента может оказаться достаточно большим и структура его может быть довольно сложной. Можно сохранять где-либо все необходимые данные, а в Perl передавать указатель на то место, где они лежат. Конечно производительность такого решения может быть ниже, чем у шаблонов на PHP. Но тем не менее препятствий для реализации я не вижу
Вот пример, который будет использовать один объект Smarty:
Если Вы посмотрите исходники того-же Smarty (раз уж о нем речь), то заметите, что конструктор класса Smarty, впрочем как и функция clear_all_assign(), занимают по 1 строке кода и соответственно выполняются весьма быстро. Что не скажешь о функции display(), которую Вы предлагаете запускать для каждого экземпляра Компонентов 2.0. примененного на странице.
Если добавить к этому вызов Smarty для всей остальной части сайта, получаем фильм ужасов в стиле старины Крюгера.
PS Вышеприведенный пример с легкостью реализуется пришибанием каждого экземпляра Smarty после его использования - разницы практически никакой.
Но ничего не мешает вместо вызова display() собирать все данные всех вызываемых компонентов в единую структуру данных и ее одну передавать в Smarty, а после этого единожды вызывать display().
Соотвтетственно в эту же структуру можно поместить и HTML текущей страницы (как пример
В каждом конкретном случае вывернуть "на изнанку" выполнение очевидно можно, если собирать куски HTML'я и параметры вызова шаблона в функции движка шаблонизации, а потом по окончании формирования всего HTML обработать все собранное и отдать Smarty. В общем случае с обеспечением совместимости со всеми задекларироваными технологиями это сделать уже совсем не так просто.
Обеспечение совместимости... естественно этот метод не позволит со 100% вероятностью подцепить шаблонизатор к абсолютно любому существующему проекту, однако если разрабатывать проект изначально под шаблонизатор, то никаких сложностей пока не замечено. Из плюсов:
1. Единые шаблоны для ВСЕГО сайта.
2. Единое место подключения шаблонизатора.
3. Единое место передачи данных в шаблонизатор.
4. Возможность организовывать модульность шалонов как заблагорассудится, не приваязываясь к компонентам и модулям, использованным на странице.
5. Вызывая компонент нет необходимости думать о том, с каким шаблоном он будет выводиться
Поэтому пункты 1-3 выполняются в рамках компонента. Но не в рамках сайта.
Пункт 4 я честно говоря не очень понял. Что именно под этим подразумевается?
По 5 пункту тоже не совсем понятно. Если у вас структура такая, как я предполагаю, то на первый взгляд я вижу не только трудности с такими инструментами, как визуальный редактор, но и некоторые организационные трудности при разработке сайта...
То есть такою работу можно организовать на конкретном сайте. Но не в качестве решения по умолчанию, предлагаемого продуктом.
Возможно мы друг друга не до конца понимаем. Если это так, то не могли бы Вы высказать свои пожелания письмом с более подробной информацией, или в тикет техподдержки, или на форуме. В комментариях к сообщениям блога не очень удобно общаться - они не предназначены для этого.