<?php

/*
* Simple DOM-based templating class by Thomas Smit created 16/02/2007
* Last edited 23/02/2007
*/

class domtemplate
{

    private 
$dom;      // @var object $dom - hold the DOM object
    
private $xpath;    // @var object $xpath - hold the XPath object
    
private $root;     // @var object $root - base HTML element

    
const CONTENTTYPE 'text/html;charset=UTF-8';    // @const str CONTENTTYPE - content-type of the document

    /*
    * domtemplate::__construct() - set up some variables/config etc.
    * @param str $file - template file to use
    * @return void
    */

    
public function __construct($file)
    {
        if(!
file_exists($file))
            
trigger_error('Template file ' $file ' does not exist'E_USER_ERROR);

        
$this->dom = new DomDocument();
        
$this->dom->loadHTMLFile($file);
        
$this->setroot();

        
$this->xpath = new DomXPath($this->dom);

        if(!
headers_sent())
            
header('Content-type: ' self::CONTENTTYPE);
    }

    
/*
    * domtemplate::setroot() - set the position to write from
    * @param str $query - query to start writing from - defaults to <body>
    * @return void
    */

    
public function setroot($query NULL)
    {
        
$this->root = (is_null($query))
            ? 
$this->dom->getElementsByTagName('body')->item(0)
            : 
$this->query($query)->item(0);
    }

    
/*
    * domtemplate::__set() - set an element's value
    * @param str $elem - element to set
    * @param str $val - value to set it to
    * @return void
    */

    
public function __set($elem$val)
    {
        
$this->dom->getElementsByTagName($elem)->item(0)->nodeValue $val;
    }

    
/*
    * domtemplate::setbyid() - set an element's value by id
    * @param str $id - id of element to set
    * @param str $val - value to set it to
    * @return void
    */

    
public function setbyid($id$val)
    {
        
$this->dom->getElementById($id)->nodeValue $val;
    }

    
/*
    * domtemplate::write() - write content to the tree
    * @param str $elem - element to create
    * @param str $val - value to set
    * @param boolean $prepend - whether to prepend or append the new node
    * @param array $attribs - element attributes in an 'attribute' => 'property' array
    * @return void
    */

    
public function write($elem$val$prepend false$attribs = array())
    {
        if(!
is_array($attribs))
            
trigger_error('Attributes must be fed as an associative array'E_USER_WARNING);

        
$content $this->dom->createElement($elem$val);
        
$node = ($prepend)
            ? 
$this->root->insertBefore($content$this->root->firstChild)
            : 
$this->root->appendChild($content);

        foreach(
$attribs as $attrib => $val)
            
$node->setAttribute($attrib$val);
    }

    
/*
    * domtemplate::create() - create raw HTML
    * @param str $content - content to write
    * @return void
    */

    
public function create($content)
    {
        
$write $this->dom->createDocumentFragment();
        
$write->appendXML($content);
        
$this->root->appendChild($write);
    }

    
/*
    * domtemplate::query() - execute an XPath query
    * @param str $query - query to run
    * @return mixed
    */

    
public function query($query)
    {
        
$result $this->xpath->evaluate($query);
        return (!
is_object($result) || !is_array($result))
            ? 
$result
            
$this->xpath->query($query);
    }

    
/*
    * domtemplate::__destruct() - output the HTML
    * @return void
    */

    
public function __destruct()
    {
        echo 
$this->dom->saveHTML();
    }

}

?>