Блочное кэширование html-кода в XSLT

Материал из Umicms
Версия от 21:34, 27 июля 2011; VITL' (обсуждение | вклад) (Новая страница: «В данной статье будет приведен пример небольшого кастомного php-макроса, с помощью которог…»)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к:навигация, поиск

В данной статье будет приведен пример небольшого кастомного php-макроса, с помощью которого можно закешировать определенный html-блок сайта, допустим список разделов каталога. В стандартном xsl шаблоне происходит начальный вызов, xsl:apply-templates, потом полученные xml-данные обрабатываются, далее происходят дополнительные вызовы для получения необходимых данных. Для очень высоко нагруженного сайта, одним из идеальных вариантов было бы кеширование не xml-данных, которые потом еще надо обработать, а итогового html-кода, одного из блоков страницы сайта. Рассмотрим пример метода для реализации нашей задачи:

public function categoryCache(){

  $xsltDom = new DomDocument;
  $xsltDom->resolveExternals = true;
  $xsltDom->substituteEntities = true;
  // $filePath - путь к xsl-шаблону трансформации от корня сайта.
  $filePath = SYS_XSLT_PATH . '/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-шаблоне


Пример шаблона 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>