DOM vs. Template

    Troels Knak-Nielsen
    Share

    Fredrik Holmström recently posted a small template engine, based on DOM-manipulation. While there are certainly a lot of template engines around, I find this approach interesting. The concept is simple enough; The template is parsed into an object model (DOM), and then values can be assigned to these through PHP code. The main difference to traditional template engines (Such as Smarty), is that the template it self doesn’t have any imperatives within. In fact, the template doesn’t even have to be written to the template engine, to be used – Any markup can be used as a source.

    Since the template can’t contain any view-logic, it ends up in a separate place (In PHP code). This makes the separation between presentation and logic airtight, which was the main idea of template engines in the first place. Another benefit is that since there is no string-level manipulation, it is virtually impossible to inadvertently get injections-type security breaches.

    The template may be unaware of the view-logic, but the opposite can’t be said. To bind values to the template, the view-logic needs to be aware of the internal structure of the template. This means that if the template changes, so must the view-logic. To decouple this dependency, we need some kind of abstraction.

    Luckily it just so happens that there is a very convenient mechanism for that; Element id‘s can be used to address central nodes in the markup. They do however have the rather annoying limitation (For this use), that they must be globally unique to the document. A better candidate then, is to use classes (The HTML attribute – I’m not talking of PHP classes) to address elements.

    The really nice thing about using classes is that it’s very unobtrusive to the markup. One will have to add classes, but since they would have to go on central elements in the markup, they would be prime candidates for reusing as fix points for CSS rules and for Javascript code. Instead of being superfluous markers in the HTML code, they actively help to write better markup.

    That sounds good in theory, so to see how it holds out in reality, I mocked together a small prototype. Even with a very limited API, it has a remarkably good expressiveness:

    Simple variable binding

    
    $t = new Domling('<p class="hello"></p>');
    $t->capture('hello')->bind("Hello World");
    echo $t->render();
    
    
    <p class="hello">Hello World</p>
    

    Switching a block out

    
    $t = new Domling('<p>Lorem Ipsum</p><p class="message">Hidden message</p>');
    $t->capture('message');
    echo $t->render();
    
    
    <p>Lorem Ipsum</p>
    

    Putting it back in

    
    $t = new Domling('<p>Lorem Ipsum</p><p class="message">Hidden message</p>');
    $block = $t->capture('message');
    $block->bind();
    echo $t->render();
    
    
    <p>Lorem Ipsum</p>
    <p class="message">Hidden message</p>
    

    And looping over a block

    
    $t = new Domling('<ul class="links"><li class="link"><a class="anchor" href="#">title</a></li></ul>');
    $links = array(
      'Sitepoint' => 'http://www.sitepoint.com',
      'Example' => 'http://www.example.org?foo=bar&ding=dong');
    foreach ($links as $title => $link) {
      $t->sequence('link', 'links')->bind(array('anchor:href' => $link, 'anchor' => $title));
    }
    echo $t->render();
    
    
    <ul class="links">
    <li class="link"><a class="anchor" href="http://www.sitepoint.com">Sitepoint</a></li>
    <li class="link"><a class="anchor" href="http://www.example.org?foo=bar&amp;ding=dong">Example</a></li>
    </ul>
    

    If you’re curious, you can get the full source code for the above examples from here: http://php.pastebin.com/f76ba8d70

    But please mind that this is just a proof-of-concept; There are probably a few quirks that should be ironed out before this could be used in production.