UPDATE
Jezeli macie ochote to przetestujcie ten system i napiszcie co o tym sadzicie. Ewentualne pytania dot dzialania i dokladnego uzycia klasy na PM
plik klasy:
  1. <?php
  2. require_once("Template/Exception.class.php");
  3. class Template{
  4. public $xml;
  5. public $xml_version;
  6. public $xml_encoding;
  7. public $xsl;
  8. public $xsl_path;
  9. public $cacheDir = "cache/";
  10. public $xslContents;
  11. protected $xslSum;
  12. protected $xmlSum;
  13. public $cache=false;//ze wzgledu na xsl:imports =/ trzeba pomyslec jak wypelnic wszystkie zmienne w tpl jakimis defaultami
  14. private $xslSheet;
  15. private $xslProcessor;
  16. public $allowPHP=false;
  17. public $dictionaryDir="./";
  18. private $dictionaryFilePath;
  19.  
  20.  
  21. private function is_array_asc($array)
  22. {
  23. if(is_array($array) && !is_numeric(array_shift(array_keys($array))))
  24. {
  25. return true;
  26. }
  27. return false;
  28. }
  29. public function setLanguage($lang=null)
  30. {
  31.  
  32. if($this->dictionaryFilePath)
  33. throw new Template_Exception("Language file already defined!");
  34.  
  35. if(file_exists($lang.".xml"))
  36. $this->dictionaryFilePath=$lang.".xml";
  37.  
  38. elseif(file_exists($this->dictionaryDir.$lang.".xml"))
  39. $this->dictionaryFilePath=$this->dictionaryDir.$lang.".xml";
  40.  
  41. else
  42. throw new Template_Exception("Language file doesn't exists");
  43.  
  44. $documentfragment = $this->xml->createDocumentFragment();
  45. $documentfragment->appendXML(file_get_contents($this->dictionaryFilePath));
  46. $this->xml->documentElement->appendChild($documentfragment);
  47. }
  48. public function __construct($xsl=null,$allowPHP=null,$xml_version=null,$xml_encoding=null)
  49. {
  50.  
  51.  
  52. $allowPHP?$this->allowPHP=true:$this->allowPHP=false;
  53. $xml_version?$this->xml_version=$xml_version:$this->xml_version="1.0";
  54. $xml_encoding?$this->xml_encoding=$xml_encoding:$this->xml_encoding="UTF-8";
  55. //create DOMDocument
  56. $this->xml = new DOMDocument($this->xml_version,$this->xml_encoding);
  57. $this->xml->appendChild($this->xml->createElement('root'));
  58. if($xsl)
  59. $this->setTemplate($xsl);
  60. }
  61. public function setTemplate($xsl)
  62. {
  63. if(file_exists($xsl))
  64. {
  65. $this->xsl_path=$xsl;
  66.  
  67. }
  68. elseif(file_exists($this->templateDir.$xsl))
  69. {
  70. $this->xsl_path=$xsl;
  71. }
  72. else
  73. {
  74. throw new Template_Exception("File:".$xsl." doesn't exists");
  75. }
  76.  
  77. $this->xslContents = file_get_contents($this->xsl_path);
  78. $this->xslSheet = new DomDocument;
  79. $this->xslSheet->loadXML($this->xslContents);
  80. $this->xslSheet->documentURI = $this->xsl_path;
  81. $this->xslProcessor = new XSLTprocessor();
  82. $this->xslProcessor->setParameter('',"xmlns",'"http://www.w3.org/1999/xhtml');
  83.  
  84. //jezeli zezwolimy templakowi na uzywanie funkcji php to mozemy je w templacie
  85. //wykonac nastepujaco : <xsl:value-of select="php:function('nl2br',string(MessageContent/Message))" disable-output-escaping="yes"/>
  86. //lub tez <xsl:value-of select="php:function('dateLang')" />
  87. /* 
  88. <?php
  89.  
  90. function getNodeSet() {
  91.  $xml =
  92.  "<test>" .
  93.  "<a-node>This is a node</a-node>" .
  94.  "<a-node>This is another node</a-node>" .
  95.  "</test>";
  96.  $doc = new DOMDocument;
  97.  $doc->loadXml($xml);
  98.  return $doc;
  99. }
  100.  
  101. ?>
  102. <xsl:template match="/">
  103.  <xsl:apply-templates select="php:function('getNodeSet')" />
  104. </xsl:template>
  105. <xsl:apply-templates select="php:function('getNodeSet')" mode="discardRoot" />
  106.  
  107.  
  108. */
  109. if($this->allowPHP)
  110. {
  111. //xmlns:php="http://php.net/xsl"
  112. $this->xslProcessor->setParameter('', 'xmlns', 'asdasd' );
  113. $this->xslProcessor->registerPHPFunctions();
  114. }
  115.  
  116. $this->xslProcessor->importStyleSheet($this->xslSheet);
  117. //print_r($this->xslProcessor->transformToDoc($this->xml)->saveXML());  //to moze juz posluzyc jako cache ale brakuje mi zmiennych :(
  118. //niestety tymczasowo cache trzeba usunąć i pomyśleć nad tym, zostawiam jako opcje ale narazie lepiej nie uzywac
  119.  
  120. //cache ponizej
  121. if($this->cache)
  122. $this->xslSum = md5($this->xslContents);
  123. }
  124. private function array_to_xml($key,$value)
  125. {
  126. if($this->is_array_asc($value))
  127. {
  128. $data .= "<".$key.">";
  129. foreach($value as $k => $v)
  130. {
  131. if(is_array($v))
  132. $data.=$this->array_to_xml($k,$v);
  133. else
  134. $data.="<$k>".$v."</$k>";
  135. }
  136. $data .= "</".$key.">";
  137. }
  138. else
  139. {
  140. foreach($value as $v)
  141. {
  142. $data .= "<".$key.">";
  143. if(is_array($v))
  144. $data.=$this->array_to_xml($k,$v);
  145. else
  146. $data.="<value>".$v."</value>";
  147. $data .= "</".$key.">";
  148. }
  149. }
  150.  
  151. return $data;
  152. }
  153.  
  154. /*
  155. settig values
  156.  */
  157. public function set($key,$value)
  158. {
  159. if(is_array($value))
  160. {
  161. $documentfragment = $this->xml->createDocumentFragment();
  162. $documentfragment->appendXML($this->array_to_xml($key,$value));
  163. $this->xml->documentElement->appendChild($documentfragment);
  164. }
  165. else
  166. $this->xml->documentElement->appendChild($this->xml->createElement($key,$value));
  167. }
  168. public function __set($key,$value)
  169. {
  170. $this->set($key,$value);
  171. }
  172. public function setDictionaryDir($dir)
  173. {
  174. $this->dictionaryDir = $dir;
  175. }
  176. private function touchCache($filePath)
  177. {
  178. $f= fopen($filePath,"w");
  179. fclose($f);
  180. }
  181. public function checkCache()
  182. {
  183.  
  184. if(file_exists($this->cacheDir.$this->xslSum))
  185. if(file_exists($this->cacheDir.$this->xmlSum))
  186. return true;
  187. else
  188. {
  189. $this->touchCache($this->cacheDir.$this->xmlSum);
  190. return false;
  191. }
  192. else
  193. {
  194. $this->touchCache($this->cacheDir.$this->xslSum);
  195. return false;
  196. }
  197. }
  198. private function saveXhtml($content)
  199. {
  200. $f = fopen($this->cacheDir."f_".$this->xslSum,"w");
  201. fwrite($f,$content);
  202. fclose($f);
  203. }
  204. public function applyTemplate()
  205. {
  206. if(!$this->xsl_path)
  207. throw new Template_Exception("Template file not set");
  208. if($this->cache)
  209. {
  210. $this->xmlSum = md5($this->xml->saveXML());
  211. if($this->checkCache())
  212. $xhtml = file_get_contents($this->cacheDir."f_".$this->xslSum);
  213. else
  214. {
  215.  
  216. $xhtml = $this->xslProcessor->transformToXML($this->xml);
  217. $this->saveXhtml($xhtml);
  218. }
  219. }
  220. else
  221. {
  222.  
  223.  
  224. $xhtml = $this->xslProcessor->transformToXML($this->xml);
  225.  
  226. }
  227.  
  228. echo $xhtml;
  229. //echo $this->xml->saveXML();
  230. }
  231.  
  232. }
  233.  
  234. ?>

plik: Template/Exception.class.php
  1. <?php
  2. class Template_Exception extends Exception
  3. {
  4. public function __construct($message=null, $code=0)
  5. {
  6. echo "Error in a file:".$this->getFile()." on line:".$this->getLine()."<br/>".$message;
  7. }
  8. }
  9. ?>



plik index.php

  1. <?php
  2. include "Template.class.php";
  3. for($i=0;$i<10;$i++){
  4. $data[] = $i*mt_rand(12,12);
  5. }
  6.  
  7.  
  8. $tpl = new Template("tpls/tpl.xsl",true);
  9. $tpl->setDictionaryDir("Dictionary/");
  10. $tpl->setLanguage("pl");
  11.  
  12. $tpl->loop=$data;//wyslanie do templaka zmiennej loop o wartosci data
  13. $tpl->title="asa";//wylanie do templaka zmiennej asa
  14.  
  15.  
  16.  
  17. $tpl->applyTemplate();
  18.  
  19.  
  20.  
  21. ?>


plik szablonu tpl.xsl:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <xsl:stylesheet xmlns="http://www.w3.org/1999/xhtml" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:php="http://php.net/xsl">
  3.  
  4. <xsl:import href="plugin.xsl"/>
  5.  
  6. <xsl:output method="xml" version="1.0" media-type="text/html" doctype-public="-//W3C//DTD XHTML 1.1//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" encoding="utf-8"/>
  7.  
  8. <xsl:template match="/">
  9.  
  10.  
  11. <html xmlns="http://www.w3.org/1999/xhtml">
  12. <head>
  13. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  14. <title>
  15.      <xsl:value-of select="//title" />
  16. </title>
  17. </head>
  18.  
  19. <body>
  20. <p>
  21. <xsl:apply-imports />
  22.      <xsl:for-each select="//loop">
  23.            <xsl:value-of select="value" />data<br />
  24.            
  25.      </xsl:for-each>
  26. </p>
  27. </body>
  28. </html>
  29. </xsl:template>
  30.  
  31.  
  32.  
  33. </xsl:stylesheet>


plik plugin.xsl
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <xsl:stylesheet version="1.0" xmlns="http://www.w3.org/1999/xhtml" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl">
  3. <xsl:output method="html"/>
  4. <xsl:template match="/">
  5.      <b><xsl:value-of select="php:function('strstr',string(//title),'t')" /></b>
  6.      <span><xsl:value-of select="//dictionary/b2" /></span>
  7. </xsl:template>
  8. </xsl:stylesheet>


plik: Dictionary/pl.xml
  1. <dictionary>
  2.      <b2> bądź dwa </b2>
  3. </dictionary>



----------------------
nadal pracuje nad klasa, wymaga stworzenia cache, jezeli ktos bedzie mial pomysl to prosilbym o kontakt deirathe@gmail.com lub PM