changeset 0:c86959030ae8

Import initial
author Franck Deroche <webmaster@defr.net>
date Sat, 10 Mar 2007 21:48:42 +0100
parents
children 0f40a8a39c68
files class.template.php menu.php menu.xml simple.php simple.xml
diffstat 5 files changed, 215 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/class.template.php	Sat Mar 10 21:48:42 2007 +0100
@@ -0,0 +1,154 @@
+<?php
+class Template {
+    var $xmlDocument;
+    var $xmlXPath;
+    
+    const NS = 'http://defr.net/2007/template';
+    
+    function __construct($fileName) {
+        $this->xmlDocument->validateOnParse = true;
+        $this->xmlDocument = DOMDocument::loadXML(file_get_contents($fileName));
+        $this->xmlXPath = new DOMXPath($this->xmlDocument);
+    }
+    
+    function apply($selector, $obj) {
+        $rootSelector = $this->parseSelector($selector);
+        // Cloning test
+        if(is_array($obj)) {
+            foreach($obj as $array) {
+                foreach($rootSelector->nodes as $node) {
+                    $nodeName = key($array);
+                    $tmp = $this->getClonedNode($node, $nodeName);
+                    $futureNode = $tmp->clone;
+                    $node->insertBefore($futureNode, $tmp->orig);
+                    foreach($array as $sel => $test) {
+                        $content = $this->parseReplacement($test);
+                        $localSelector = $this->parseSelector($sel);
+                        if(isset($localSelector->attribute))
+                            $futureNode->setAttribute($localSelector->attribute, $test);
+                        else {
+                            if($futureNode->namespaceURI == Template::NS)
+                                $this->replaceNode($futureNode, $content);
+                            else
+                                $this->setNodeContent($futureNode, $content);
+                        }
+                    }
+                }
+            }
+        } else
+        {
+            $content = $this->parseReplacement($obj);
+            foreach($rootSelector->nodes as $node) {
+                if(isset($rootSelector->attribute)) {
+                    $node->setAttribute($rootSelector->attribute, $obj);
+                } else {
+                    if($node->namespaceURI == Template::NS)
+                        $this->replaceNode($node, $content);
+                    else
+                        $this->setNodeContent($node, $content);
+                }
+            }
+        }
+    }
+    
+    function getClonedNode($node, $childNodeName) {
+        $canditates = $node->getElementsByTagName($childNodeName);
+        foreach($canditates as $canditate) {
+            if($canditate->nodeName == $childNodeName && $canditate->getAttributeNS(Template::NS, 'toClone') == 'true') {
+                $tmp = array();
+                $tmp['orig'] = $canditate;
+                $cnode = $canditate->cloneNode(true);
+                $cnode->removeAttribute('toClone');
+                $tmp['clone'] = $cnode;
+                return (object)$tmp;
+            }
+        }
+    }
+    
+    function parseSelector($selector, DOMElement $root=NULL) {
+        if(!($root instanceof DOMElement)) {
+            $root = $this->xmlDocument->documentElement;
+        }
+        $obj = array();
+        $pos = strpos($selector, '@');
+        if($pos !== false) {
+            $obj['attribute'] = substr($selector,$pos +1);
+            $selector = substr($selector, 0, $pos);
+        }
+        if($selector[0] == '#') {
+            $obj['xpath'] = "//*[@t:id='" . substr($selector, 1) . "']";
+            $obj['nodes'] = $this->xmlXPath->query($obj['xpath'], $root);
+        }
+        else {
+            $obj['nodeName'] = $selector;
+            $obj['nodes'] = $root->getElementsByTagName($selector);
+            $obj['nodes'] = $this->xmlDocument->getElementsByTagName($selector);
+        }
+        return (object)$obj;
+    }
+    
+    function getNodesMatching($selector, DOMElement $root) {
+        $pos = strpos($selector, '/');
+        if($pos !== false) {
+            $currentSelector = substr($selector, 0, $pos);
+            $remainingSelector = substr($selector, $pos+1);
+        }
+        else {
+            $currentSelector = $selector;
+            $remainingSelector = NULL;
+        }
+        if($selector[0] == '#') {
+            $nodes = $this->xmlXPath->query($currentSelector, $root);
+        }
+        else {
+            
+        }
+    }
+    
+    function parseReplacement($obj) {
+        $retVal = NULL;
+        if(is_string($obj))
+            $retVal = $this->xmlDocument->createTextNode($obj);
+        else if($obj instanceof DOMDocument)
+            $retVal = $obj->documentElement;
+        else if($obj instanceof DOMNode)
+            $retVal = $obj;
+        return $retVal;
+    }
+    
+    function setParams($array) {
+        foreach($array as $selector => $obj) {
+            $this->apply($selector, $obj);
+        }
+    }
+    
+    function replaceNode(DOMNode $node, DOMNode $content) {
+        $parent = $node->parentNode;
+        $parent->replaceChild($content, $node);
+    }
+    
+    function setNodeContent(DOMElement $node, DOMNode $content) {
+        // Suppress existing childs
+        foreach($node->childNodes as $child) {
+            $node->removeChild($child);
+        }
+        // Add the new child
+        $node->appendChild($content);
+    }
+    
+    function clean() {
+        // Suppression des noeuds à cloner
+        $nodes = $this->xmlXPath->query("//*[@t:toClone]|//t:*");
+        foreach($nodes as $node) {
+            if($node->parentNode) {
+                $node->parentNode->removeChild($node);
+            }
+        }
+    }
+    
+    function __toString() {
+        $this->clean();
+        $this->xmlDocument->saveXML();
+        return $this->xmlDocument->saveXML();
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/menu.php	Sat Mar 10 21:48:42 2007 +0100
@@ -0,0 +1,14 @@
+<?php
+    require 'class.template.php';
+    $tpl = new Template('menu.xml');
+    $params = array(
+        '#monMenu' => array(
+            array('dt' => 'Test1'),
+            array('dd' => 'Truc1'),
+            array('dt' => 'Test2'),
+            array('dd' => 'Truc2')
+        )
+    );
+    $tpl->setParams($params);
+    echo $tpl;
+?>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/menu.xml	Sat Mar 10 21:48:42 2007 +0100
@@ -0,0 +1,8 @@
+<dl t:id='monMenu' xmlns='http://www.w3.org/1999/xhtml' xmlns:t='http://defr.net/2007/template'>
+  <dd t:toClone='true' />
+  <dt t:toClone='true' />
+  <t:test t:toClone='true'>
+    <t:a />
+    <t:b />
+  </t:test>
+</dl>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/simple.php	Sat Mar 10 21:48:42 2007 +0100
@@ -0,0 +1,18 @@
+<?php
+  require 'class.template.php';
+  $tpl = new Template('simple.xml');
+  $params = array(
+    'title' => 'Ceci est un test', 
+    '#hello' => 'Bonjour tout l\'monde!',
+    '#hello@class' => 'test3',
+    'test' => 'Ceci devrait remplacer l\'element test dans l\'espace de nom t.',
+    'color' => 'vert',
+    '#attr@class' => 'test',
+    '#choses' => array(
+        array('li' => 'Lorem ipsum', 'li@class' => 'test'),
+        array('li' => 'sit dolor'),
+        array('li' => 'amet.')
+    ));
+  $tpl->setParams($params);
+  echo $tpl;
+?>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/simple.xml	Sat Mar 10 21:48:42 2007 +0100
@@ -0,0 +1,21 @@
+<?xml version='1.0' encoding='utf-8'?>
+<!DOCTYPE
+    html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:t="http://defr.net/2007/template" xml:lang="fr">
+ <head>
+    <title />
+  </head>
+  <body>
+    <h1 t:id="hello">Ceci sera remplacé.</h1>
+    <p><t:test /></p>
+    <p>Ma couleur préférée est le <t:color />. Et vous ?</p>
+    <p t:id='attr'>Test sur les attributs.</p>
+    <ul t:id='choses'>
+        <li>Première chose</li>
+        <li t:toClone='true' class='ab' />
+        <li>Dernière chose</li>
+    </ul>
+    <t:ab>Ceci devrait disparaitre.</t:ab>
+  </body>
+</html>
\ No newline at end of file