Блочное кэширование html-кода в XSLT — различия между версиями
Kalexey (обсуждение | вклад) |
Mad grant (обсуждение | вклад) |
||
Строка 129: | Строка 129: | ||
</xsl:stylesheet> | </xsl:stylesheet> | ||
</source> | </source> | ||
− | + | [[Категория:Верстка в XSLT]] |
Версия 19:42, 4 июня 2013
В данной статье будет приведен пример небольшого кастомного php-макроса, с помощью которого можно закэшировать определенный html-блок сайта, допустим список разделов каталога. В стандартном xsl шаблоне происходит начальный вызов, xsl:apply-templates, потом полученные xml-данные обрабатываются, далее происходят дополнительные вызовы для получения необходимых данных. Для очень высоко нагруженного сайта, одним из идеальных вариантов было бы кэширование не xml-данных, которые потом еще надо обработать, а итогового html-кода, одного из блоков страницы сайта. Рассмотрим пример метода для реализации нашей задачи:
public function categoryCache(){
$xsltDom = new DomDocument;
$xsltDom->resolveExternals = true;
$xsltDom->substituteEntities = true;
// $filePath - путь к xsl-шаблону трансформации.
$filePath = CURRENT_WORKING_DIR . '/xsltTpls/leftCache.xsl';
$xsltDom->load($filePath, DOM_LOAD_OPTIONS);
$xslt = new xsltProcessor;
$xslt->registerPHPFunctions();
$xslt->importStyleSheet($xsltDom);
$dom_new = new DOMDocument("1.0", "utf-8");
// $xml - xml-данные для трансформации.
$xml = file_get_contents('udata://catalog/getCategoryList/void/shop/');
$dom_new->loadXML($xml);
//производим трансформацию
$result = $xslt->transformToXML($dom_new);
//html-данные необходимо включить в CDATA и в какой либо корневой узел.
$result = '<udata><![CDATA[' . $result . ']]></udata>';
// данный принцип возвращения данных отключает xslt-трансформацию системой UMI.CMS
return array('plain:result' => $result);
}
Метод можно добавить в файл classes/modules/custom.php, тогда вызов в xsl-шаблоне будет следующим:
<xsl:value-of select="document('udata://custom/categoryCache?expire=36000')/udata" disable-output-escaping="yes" />
Полученный html-код будет закэширован на час, если на сайте включен кэш. В случае необходимости, можно настроить сохранение кэша в текстовый файл на сервере, как это было сделано в данной статье Кэширование результата работы метода getCreateForm в XSL-шаблоне . Пример метода, для кэширования данных в html-файл:
public function getCategoryListCustom(){
$folder = CURRENT_WORKING_DIR . '/sys-temp/udatacache/';
$path = $folder . 'left-columnCache.xml';
if(!is_dir($folder)) mkdir($folder, 0777, true);
if(is_file($path)) $mtime = filemtime($path);
$expire = 86400;
if(!is_file($path) || time() > ($mtime + $expire)) {
$xsltDom = new DomDocument;
$xsltDom->resolveExternals = true;
$xsltDom->substituteEntities = true;
// $filePath - путь к xsl-шаблону трансформации.
$filePath = CURRENT_WORKING_DIR . '/xsltTpls/modules/catalog/leftCache.xsl';
$xsltDom->load($filePath, DOM_LOAD_OPTIONS);
$xslt = new xsltProcessor;
$xslt->registerPHPFunctions();
$xslt->importStyleSheet($xsltDom);
$dom_new = new DOMDocument("1.0", "utf-8");
// $xml - xml-данные для трансформации.
$xml = file_get_contents('udata://catalog/getCategoryList/void/shop/');
$dom_new->loadXML($xml);
//производим трансформацию
$result = $xslt->transformToXML($dom_new);
//html-данные необходимо включить в CDATA и в какой либо корневой узел.
$result = "<udata mode=\"cache\"><![CDATA[" . $result . "]]></udata>";
file_put_contents($path, $result);
// данный принцип возвращения данных отключает xslt-трансформацию системой UMI.CMS
return array('plain:result' => $result);
}else{
$result = file_get_contents($path);
return array('plain:result' => $result);
}
}
Пример шаблона leftCache.xsl:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xsl:stylesheet SYSTEM "ulang://i18n/constants.dtd:file">
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xlink="http://www.w3.org/TR/xlink"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:umi="http://www.umi-cms.ru/TR/umi">
<xsl:output encoding="utf-8" method="html" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="." mode="left-column" />
</xsl:template>
<xsl:template match="udata[@method = 'getCategoryList']" mode="left-column">
<ul class="catalog_menu" umi:button-position="bottom left" umi:element-id="{@category-id}" umi:region="list" umi:module="catalog" umi:sortable="sortable">
<xsl:apply-templates select="//item" mode="left-column" />
</ul>
</xsl:template>
<xsl:template match="udata[@method = 'getCategoryList']//item" mode="left-column">
<li umi:element-id="{@id}" umi:region="row">
<span>
<a href="{@link}" umi:field-name="name" umi:delete="delete" umi:empty="&empty-section-name;">
<xsl:value-of select="." />
</a>
</span>
<xsl:apply-templates select="document(concat('udatacache://catalog/getCategoryList/void/', @id))/udata"/>
</li>
</xsl:template>
<xsl:template match="udata[@method = 'getCategoryList']">
<ul umi:element-id="{@category-id}" umi:region="list" umi:module="catalog" umi:sortable="sortable" umi:button-position="top right">
<xsl:apply-templates select="//item" />
</ul>
</xsl:template>
<xsl:template match="udata[@method = 'getCategoryList']//item">
<li umi:element-id="{@id}" umi:region="row">
<a href="{@link}" umi:field-name="name" umi:delete="delete" umi:empty="&empty-section-name;">
<xsl:value-of select="." />
</a>
</li>
</xsl:template>
</xsl:stylesheet>