.. / Codeigniter + XSLT (шаблонизаторы маздай!)

    Постоянная тема в CI, CakePHP, Syphony и др. - как прикрутить шаблонизатор Имярек к фреймворку. В wiki CodeIgnitera насчитывается зоопарк из десятка с лишним шаблонизаторов. В отличие от прочих, XSLT является не сторонней библиотекой, а составной частью самого PHP5, скорее всего поэтому, специального описания для него CI-wiki нет.

    Ранее я сделал заготовку для CMS с гордым названием "Codeigniter CMS Embrio "™. Вот эту заготовку я сейчас и использую для прикручивания XSLT к CI. шаблонизатора. Как обычно берем заготовку блога из директории step0 архива (комментарии к заготовке см. здесь) Запускаем и убеждаемся что все работает.

    Далее я чуть-чуть модифицирую контроллер для вывод ленты записей через XSLT. Вывод одиночных записей делается аналогично.

    1. Перевод массива в XML

    Из модели мы получаем массивы, которые обычно передаются во вьюер. Нам нужно перегнать эти массивы в XML. По-хорошему эта операция должна выполняться в модели (?), но для простоты я размещу это в контроллере, а модель оставлю без изменений. В ней XML формируется обычной склейкой строк.

    /*  перевод массива простого запроса в XML  */
     function toxml($array)
        {
           $result="<root>   \n";
           foreach ($array as $key=>   $value)
           {
               $result.="\t<rec>   \n";
               foreach ($value as $k=>   $v) $result.="\t\t<".$k.">   ".$v."</".$k.">   \n";
               $result.="\t</rec>   \n";
           }
           return $result.="</root>   \n";
        }
    }

    2. XSLT трансформация

    Добавляем функцию трансформации. На входе - xml и имя шаблона xslt. Предполагается что шаблон лежит в директории /xsl/

    function XSLT($xml,$tpl)
           {
                      /* xml ->    dom */
                      $doc = new DOMDocument();
    		  $doc->   loadXML($xml);
                      /* считываем xsl */
    		  $xsl = new DomDocument();
    		  $xsl->   load('xsl/'.$tpl.'.xsl');
                      
                      /* производим трансформацию */ 
    		  $proc = new XsltProcessor();
    		  $xsl = $proc->   importStylesheet($xsl);
    		  echo $proc->   transformToXML($doc);
           }

    3. По шагам дорабатываем процедуру вывода ленты блога

    Для начала проверим что из себя представляет запрос к модели в виде xml

    function index()
    	{
            /* обращение к модели за данными */
            $data = $this->   mblog->   getAll();
            /* преобразование массива в XML */
            $xml= $this->   toXML($data);
            echo $xml;
    	}

    После запуска блога в броузер выведется

    <root> 
    	<rec>   
    		<id>   1</id>   
    		<title>   Text1</title>   
    		<author>   Zalkind</author>   
    		<mail>   info@mail.ru</mail>   
    		<anounce>   Anounce1 </anounce>   
    		<content>   Text1 Text1 Text1</content>   
    	</rec>   
    	<rec>   
    		<id>   2</id>   
    		<title>   Text2</title>   
    		<author>   Zalkind</author>   
    		<mail>   info@mail.ru</mail>   
    		<anounce>   Anounce2 </anounce>   
    		<content>   Text2 Text2 Text2</content>   
    	</rec>   
        ............................................
        ............................................
        ............................................
        ............................................
        ............................................
    </root>   

    Для преобразования его в HTML составим тривиальный XSLT-шаблон по типу того что лежит во /view/index.php

    <?xml version="1.0" encoding="UTF-8"?> 
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">   
      <xsl:template match="root">   
          <html>   
              <head>   <link rel="stylesheet" href="/css.css" type="text/css" />   
              </head>   
              <body>   
                <xsl:apply-templates/>   
              </body>   
          </html>   
      </xsl:template>   
      <xsl:template match="rec">   
         <div class="entries">   
             <h1>   <xsl:value-of select="title"/>   </h1>   
             <div class="content">   <xsl:value-of select="anounce"/>   </div>   
             <a  class="right" href="/blog/view/{id}">   more</a>   
         </div>   
     </xsl:template>   
    </xsl:stylesheet>   

    в корневой директории создадим поддиректорю /xsl/ В нее сохраним этот шаблон с именем index.xsl

    Далее еще раз скорректируем процедуру вывода блога

    function index()
    	{
            /* обращение к модели за данными */
            $data = $this->   mblog->   getAll();
            /* преобразование массива в XML */
            $xml= $this->   toXML($data);
            /* вызов XSLT - трансформации */
            $this->   XSLT($xml,'index');
    	}
    Теперь после запуска блога в броузере должно отобразиться то же самое что было до всех изменений, с той разницей что формирование выдачи идет уже через XSLT-трансформацию

    4. The End

    Все что написано выше - только простенький пример, степень упрощения которого наверное черезмерна. В реальной практике все сложнее. Основна проблема XSLT - ресурсоемкость, поэтому для более-менее нагруженных приложений необходимо задумываться о многоуровневом кэшировании. Впрочем для всякой фигни с посещаемостью не более 50 хостов в сутки ( как например этот блог) кэширования не нужно. Да его здесь и нет.

    И как обычно все исходники можно найти в директории step4 архива

    1. 2007-09-03
    1. habrahabr.ru/blogs/about_cms/22018/ - Сергей Котырев. Реабилитация XML/XSLT технологий
    2. rizhikov.habrahabr.ru/blog/18569/ - Сергей Рыжиков. Иллюзии XML-XSLT технологий
Go Index Test