Универсальный метод для кэширования html-данных в XSLT
Материал из Umicms
Версия от 11:14, 15 августа 2012; Kalexey (обсуждение | вклад)
В одной из статей уже был рассмотрен способ кэширования html-кода в XSLT, это была статья Блочное кэширование html-кода в XSLT
В данной статьей будет показан пример универсального кастомного метода, в который можно передавать основной вызов: модуль, метод, параметры и также путь к шаблону для трансформации xml данных. Кастомный метод необходимо добавить в файл classes/modules/custom.php:
public function xsltHtmlCache($expire = 3600, $module, $method){
$xslFilePath = getRequest('xsl');
// $filePath - путь к xsl-шаблону трансформации.
$filePath = CURRENT_WORKING_DIR . '/xsltTpls/' . $xslFilePath;
if(!is_file($filePath)) return;
$args = func_get_args();
$params = array_slice($args, 3);
$params_str = implode('/', $params);
$url = "udata://" . $module . '/' . $method . '/' . $params_str;
$folder = CURRENT_WORKING_DIR . '/sys-temp/udatacache/';
$path = $folder . md5($url . $filePath) . '.xml';
if(!is_dir($folder)) mkdir($folder, 0777, true);
if(is_file($path)) $mtime = filemtime($path);
if(!is_file($path) || time() > ($mtime + $expire)) {
$xsltDom = new DomDocument;
$xsltDom->resolveExternals = true;
$xsltDom->substituteEntities = true;
$xsltDom->load($filePath, DOM_LOAD_OPTIONS);
$xslt = new xsltProcessor;
$xslt->registerPHPFunctions();
$xslt->importStyleSheet($xsltDom);
$page_id = cmsController::getInstance()->getCurrentElementId();
$parent_id = "";
$active = "";
if($page_id){
$page = umiHierarchy::getInstance()->getElement($page_id);
$parent_id = $page->getParentId();
$active = (int) $page->getIsDefault();
}
// Добавляем необходимые глобальные переменные, которые можно будет использовать в xsl-шаблоне
$xslt->setParameter("", 'parent-id', $parent_id);
$xslt->setParameter("", 'document-page-id', $page_id);
$xslt->setParameter("", 'active', $active);
$dom_new = new DOMDocument("1.0", "utf-8");
// $xml - xml-данные для трансформации.
$xml = file_get_contents($url);
$dom_new->loadXML($xml);
//производим трансформацию
$result = $xslt->transformToXML($dom_new);
//html-данные необходимо включить в CDATA и в какой либо корневой узел.
$result = "<udata mode=\"cache\"><![CDATA[" . $result . "]]></udata>";
// данный принцип возвращения данных отключает xslt-трансформацию системой UMI.CMS
return array('plain:result' => $result);
}else{
$result = file_get_contents($path);
return array('plain:result' => $result);
}
}
Вызов может быть следующим:
<xsl:value-of select="document('udata://custom/xsltHtmlCache/3600/catalog/getCategoryList//8//1?xsl=modules/catalog/category-cache.xsl')/udata"
disable-output-escaping="yes" />
Обратите внимание в кастомном методе на блок:
// page_id текущей страницы сайта
$page_id = cmsController::getInstance()->getCurrentElementId();
$parent_id = "";
$active = "";
if($page_id){
$page = umiHierarchy::getInstance()->getElement($page_id);
$parent_id = $page->getParentId();
$active = (int) $page->getIsDefault();
}
// Добавляем необходимые глобальные переменные, которые можно будет использовать в xsl-шаблоне
$xslt->setParameter("", 'parent-id', $parent_id);
$xslt->setParameter("", 'document-page-id', $page_id);
$xslt->setParameter("", 'active', $active);