
[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 скрипт из функции подключения движка шаблонизации вполне можно:
function PerlEngine($templateFile, $arResult, $arParams, $arLangMessages, $templateFolder, $parentTemplateFolder, $template) { * * * exec("perl ".$_SERVER["DOCUMENT_ROOT"].$templateFile." > /dev/null"); }Вопрос будет в передаче параметров Perl скрипту. Массив результатов работы компонента может оказаться достаточно большим и структура его может быть довольно сложной. Можно сохранять где-либо все необходимые данные, а в Perl передавать указатель на то место, где они лежат. Конечно производительность такого решения может быть ниже, чем у шаблонов на PHP. Но тем не менее препятствий для реализации я не вижу
Вот пример, который будет использовать один объект Smarty:
$smarty = null; function SmartyEngine($templateFile, $arResult, $arParams, $arLangMessages, $templateFolder, $parentTemplateFolder, $template) { if (!defined("SMARTY_DIR")) define("SMARTY_DIR", "d:/Projects/Siteman/wizard/smarty/libs/"); require_once('d:/Projects/Siteman/wizard/smarty/libs/Smarty.class.php'); global $smarty; if (!isset($smarty) || !is_object($smarty)) { $smarty = new Smarty; $smarty->compile_dir = "d:/Projects/Siteman/wizard/smarty/templates_c/"; $smarty->config_dir = "d:/Projects/Siteman/wizard/smarty/configs/"; $smarty->template_dir = "d:/Projects/Siteman/wizard/smarty/templates/"; $smarty->cache_dir = "d:/Projects/Siteman/wizard/smarty/cache/"; $smarty->compile_check = true; $smarty->debugging = false; } else { $smarty->clear_all_assign(); } $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, впрочем как и функция 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 пункту тоже не совсем понятно. Если у вас структура такая, как я предполагаю, то на первый взгляд я вижу не только трудности с такими инструментами, как визуальный редактор, но и некоторые организационные трудности при разработке сайта...
То есть такою работу можно организовать на конкретном сайте. Но не в качестве решения по умолчанию, предлагаемого продуктом.
Возможно мы друг друга не до конца понимаем. Если это так, то не могли бы Вы высказать свои пожелания письмом с более подробной информацией, или в тикет техподдержки, или на форуме. В комментариях к сообщениям блога не очень удобно общаться - они не предназначены для этого.