appendChild($node->ownerDocument->createElement('child', 'somevalue')); $newNode = $node->ownerDocument->createElement('child', 'somevalue'); return $node; } function Item($node){ return $node->ownerDocument->createElement('li', 'somevalue'); } } trait Lifty { function bind(){ if ($this->hasChildNodes()) { foreach ($this->childNodes as $child){ $child->bind(); } } if ($this->hasAttributes()) { foreach ($this->attributes as $index => $attr){ if ($index == 'lift'){ $val = $attr->value; list($class, $method) = split('::', $val); $ret = $class::{$method}($this); $this->parentNode->replaceChild($ret, $this); } } } } } class LiftTemplate extends DOMDocument{ use Lifty; } class LiftNode extends DOMNode{ use Lifty; } class LiftDocumentType extends DOMDocumentType{ use Lifty; } class LiftElement extends DOMElement{ use Lifty; } class LiftText extends DOMText{ use Lifty; } class LiftComment extends DOMComment { use Lifty; } class LiftProcessingInstruction extends DOMProcessingInstruction { use Lifty; } class ViewParser { public function __construct($document){ $doc = new LiftTemplate(); $doc->registerNodeClass('DOMNode', 'LiftNode'); $doc->registerNodeClass('DOMElement', 'LiftElement'); $doc->registerNodeClass('DOMText', 'LiftText'); $doc->registerNodeClass('DOMComment', 'LiftComment'); $doc->registerNodeClass('DOMDocumentType', 'LiftDocumentType'); $doc->registerNodeClass('DOMProcessingInstruction', 'LiftProcessingInstruction'); $doc->LoadHTMLFile($document); $doc->bind(); echo $doc->saveHTML(); } } $view = new ViewParser('homepage.html');