Patroon - a Javascript Template Engine

September 9, 2008

Patroon is a template engine written in Javascript in about 100 lines of code. It takes existing DOM nodes annotated with CSS classes and expand a data object according to simple rules. Additionally you may use traditional string interpolation inside attribute values and text nodes.

Patroon has its own project page now! Please look for current information there.

Example

Comments in this blog are stored as a list of JSON objects, I wrote about it here. So think about a data object like this:

  1. var data = {
  2. comment: [{
  3. date: "2008-09-07 12:28:33",
  4. name: "David Beckham",
  5. website: "beckham.com",
  6. text: "I watched the euro finals on tv..."
  7. }, {
  8. date: "2008-09-07 14:28:33",
  9. name: "Tuncay",
  10. website: "",
  11. text: "Me too"
  12. }]
  13. };

This data will be expanded with help of following template:

  1. <div class="comments">
  2. <div id="comments-template">
  3. <div class="comment">
  4. <div class="_ top">
  5. <a class="_" href="{website}">{name}</a> said
  6. <a class="_" title="{time}"></a>:
  7. </div>
  8. <div class="text"></div>
  9. </div>
  10. </div>
  11. </div>

The javascript to actually execute this template looks like this:

  1. // The comments template will be removed from the DOM!
  2. var template = new Template('comments-template');
  3. // template will result in a new DOM node
  4. var result = template.expand(data);
  5. // insert the resulting node into the comments container
  6. var container = document.getElementsByClassName('comments')[0];
  7. container.appendChild(result);

Using jQuery the code gets a bit cleaner:

  1. // The comments template will be removed from the DOM!
  2. var template = new Template('comments-template');
  3. // Expand the template into the comments section
  4. $('.comments').expand(template, data);

Basic Rules

There are 5 basic rules:

  • Strings and Numbers are inserted by innerHTML to the current node.

  • Arrays repeat the current node and process its elements recursively in same scope.

  • Objects trigger a class name lookup by property name. The value of each property is expanded recursively in new scope.

  • Code will be evaluated for text surounded with braces (Works also for attributes).

  • Processing child nodes will be triggered for nodes with a class attribute starting with _.

I admit the last point is a bit quirky, but processing all child nodes per default is too expensive and too unpredictable. Maybe I will find a better way, but I don’t mind inserting these extra _ class names.

Evaluation

So speaking of the example data, this would mean following algorithm:

  • Find the first node with a class name of comment.

  • Repeat this node two times and recursively process the first and second comment.

  • Descend into the node with class top.

  • Descend into the first link node.

  • Evaluate the code found in the href attribute and in the text.

  • Descend into the second link node.

  • Evaluate the code found in the title attribute.

  • Find the first node with the class text.

  • Insert the the text of the comment into the found node.

Note that we are dealing with two scopes here: the global scope and the comment scope. The global scope just contains a name comment and the comment scope contains the names date, name, website and text.

Download

Download the script at my github repository.


Posted in category Javascript by Matthias Georgi. Tagged with template, json.
Similar Posts