The KiTE – template engine for JavaScript


Preface

Modern Web applications frequently use AJAX kind of client/server interaction. They receive data from the server in pure JSON format. That means instead of generating markup on the server such applications are composing HTML inside the browser (on client side).

Straightforward approach is to use string concatenation spagetti like : "<b>" + data + "</b>".  But this almost always will end up in non-maintainable mess. Real Jedi use markup templates. Typical PHP page is a script with embedded HTML – typical template the gets "instantiated" for the particular GET request/data/user.

PHP or plain old ASP are not only possible template formats. There are a lot of template engines and template languages in the wild. All of them fall into four major groups:

  1. Minimalistic, logic-less: {{mustache}} and (probably) PURE;
  2. Still simple TDLs but with some simple logic like if/else construcs: jQuery.tmpl() and the KiTE,
  3. PHP or ASP alike templates: JavaScript constructs embedded in HTML using <% %> brackets: jQote, John Resig’s Micro Templates, EJS, etc.
  4. Group of template engines based on #haml/Ruby ideas – they use special non-HTML markup.

In general: as simple language, less syntax noise it creates – as better. Easier to comprehend and so easier to maintain. The worst case from this perspective is actually PHP (group #3) – mix of two different syntaxes in single source (script and markup) can easily become not readable.  

Speed of template instantiation is on other axis of "templates space". Implementation of PHP alike templating (group #3) is relatively straightforward with JavaScript. Basic idea is to replace all text between
"%> ... some markup... <%"  
by something like
 out += "... some markup...";  
and wrap the template into
 compiled = new Function(transformed_template).

Template instantiation in this case is a matter of calling such function. This approach potentially is as fast as JavaScript itself. But as I said the template source is too "dirty" even in simple cases. I believe that code from this article http://blog.futtta.be/2011/01/18/how-to-do-jquery-templates-with-jqote2/ is a good example of how messy it can be with just few if/else’s.

On other side {{mustache}} templates are pretty clean but current {{mustache}} implementation is extremely slow. According to jsperf.com/dom-vs-innerhtml-based-templating/96 it is 150 times slower than the most effective jQote2. Too bad to be honest.

Another problem with the {{mustache}} is its logic-less nature. I understand the motivation but in reality some simple logic is required. Something like "if fieldA > 10 then render the record one way otherwise in some other".

So I came up with …

The KiTE.

KiTE is lightweight (180 lines of code) and fast JavaScript template engine. It uses template defintion language (TDL) that is close to {{mustache}} but with few additions: conditional sections and custom formatting functions.

Here is an example of KiTE template that emits simple list of contacts:

<ul>
  {{#contacts}}
    <li><b>{{firstName}}</b> <i>{{lastName}}</i></li>
  {{/contacts}}
</ul>

When given by JS data in following format:

{ contacts:
  [ { firstName: "Ernest", lastName:"Hemingway" },
    { firstName: "Scott", lastName:"Fitzgerald" } ]
}

the template will be instantiated as this list:

  • Ernest Hemingway
  • Scott Fitzgerald

KiTE templates can be placed in

<script type="text/x-kite">
  ...
</script>

sections on the page so they will not polute JavaScript code.

You can use this document http://terrainformatica.com/kite/test-kite.htm to get a feeling of the KiTE templates.

Idea behind KiTE implementation, defintion of TDL and the kite() function are all explained here code.google.com/p/kite/

And the last: the name "KiTE" is an acronym of "KiTE is a Template Engine".

8 thoughts on “The KiTE – template engine for JavaScript”

  1. interesting, but regarding the jqote2 example: the problem could be with the author, he’s a messy coder 🙂

    regarding kite:
    * how does it compare with jQote2 and others speed-wise?
    * how does it handle data which can’t be put into the template as is (e.g. from the jqote2 example how departure time is calculated based on a timestamp and the delay in seconds)?

  2. Hi, Frank.

    There is a link in the article to speed comparison tests on jsPerf :
    http://jsperf.com/dom-vs-innerhtml-based-templating/96 and above.
    I also have my own test:
    http://terrainformatica.com/kite/speed-test.htm – it checks a bit different scenario – generation of a list that contains 100 items.

    I think that KiTE is fastest TE in groups #1 and #2 (in my classification above) so far.

    As of that jQote2 example… Well, it is real code for real situation so it counts.

  3. And about this:
    “* how does it handle data which can’t be put into the template as is (e.g. from the jqote2 example how departure time is calculated based on a timestamp and the delay in seconds)?”

    Two possible solutions:
    1) Either to modify the data itself so data will have a field ‘delayedTo’ or
    2) To create your own field formatter function.

    Formatter function in KiTE gets two parameters function frm(val,inobj).
    Last parameter is a context object – record where the val was taken from.

    So the formatter will look like:

    kite.formatters["delayed-time"] = function( v, obj )
    {
      return toTimeString(v + obj.delay * 1000);
    }

    And that part of the template will look like:

    {{? delay }}
       {{time|delayed-time}}
    {{^?}}
       {{time|time}} 
    {{/?}}
    
  4. wow, the formatter function looks great!

    regarding your speed-test, jqote2 and kite seem to be pretty competitive; I did 4 tests and jQote and Kite each “won” 2 of them! but why do you extract the contact-values out of ‘this’ to a new array and use that array to populate the list in the jqote-template?

  5. Andrew, I don’t know where this can be published, but I think that you must know about these guys – appcelerator.com. They do the same as you but have some cool features in compete with Sciter – clear JavaScript which is compiled to NATIVE code for ANY platform (Win, Mac, Linux, iOS, Android), moreover they use Apache 2 license. This is awesome!

  6. Conditional undefined doesn’t work?

    {{? delay }}
       {{time|delayed-time}}
    {{^?}}
       {{time|time}}
    {{/?}}

    From your example, if delay is undefined, I get an error. Please make it so that if delay is undefined the eval result is false!

Comments are closed.