Ecma Script Template Engine 18

Lately, I’ve been feeling quite creative. I guess I can thank World of Warcraft for that. Or actually the other way around. I got out of my addiction after a week in USA and I decided that I would not touch it again.

Lately I’ve been looking at simpler ways to output data received from an RPC/REST backend (usually JSON) and I even played around a bit with TrimPath’s JavaScript Templates (JST). However I didn’t like JST a whole lot. It introduces new syntax and it just felt inneficient not being able to use JavaScript syntax and semantics. And of course there was the NIH issue as well ;-)

So, while riding home from work I thought; Why not use JSP syntax? It should be trivial to implement and implementing the actual template engine didn’t take more than an hour or so. The engine supports the following 4 JSP constructs:

<%-- Comment --%>
<%= "String Expression" %>
<% expression %>
<% out.write("String Expression") %>

out is an object that implements write and writeln, for example the document in an HTML document. This allows more procedural code to be used instead of the sometimes very verbose and distracting JSP syntax.

My initial name for this was JsTemplate but that was a bit too similars to what TrimPath was using (I wasn’t even thinking about a name when I started this… I just wanted to prove that such a thing could easily be implemented and also prove that it is quite useful.) After brain storming about a name with Emil we came up with ESTE – EcmaScript Template Engine.

Enough talking. How about some sample code?

var templateString = "<p>hello" +
   "<% for (var i =0; i < 100; i++) {%>" + 
      "<%-- this is a comment --%>" +
      "<%= \"world \" + i %>!<br>" + 
   "<% } %>" +
   "</p>";
TemplateEngine.parse(templateString , document);

There is a quite extensive demo in /playround/este/.

Once I got the basic template engine I thought about a few scenarios and since I’ve been doing a lot of JSON lately I thought that I should try to make it easier to use the engine with data encoded using JSON.


var s = TemplateEngine.parse("My name is < %= name.first %> < %= name.last %>", 
   writer,
   '{"name":{"first":"Erik","last":"Arvidsson"}}');

In general it isn’t too nice to write these templates inside javascript strings so you might want to use a function like readTextFile.

  • soy

    That’s just sad, Erik.

    The world is finally moving away from code intermixed with content and you help bring it back to life? :)

    When I saw that terrible JST I was sincerely hoping no one in their right mind would think to use it. Templates that allow code are just recipes for disaster, see the traditional uses of PHP, ASP, etc. A maintainance nightmare and very little encapsulation and logic.

    Even MS realized this and moved to the ASP.NET model, which is terrible for many other reasons, but at least it had the right idea.

    Ideally, data should be returning in raw format from the server (XML, ‘JSON’, CSV) and properly encapsulated and componentized code should handle the data in context. Returning extended logic from the server via ‘Templates’ will only continue the trend of messy unmanagable applications.

    Now, I know you know all this, because Bindows (regardless of how badly it was named) is done properly and directs the developer towards a cleaner development concept, with data binding and encapsulated namespaces. This is why I’m so surprised by your attempt to join the templates wagon :-\.

  • http://www.pontukom.com Guilherme Blanco

    Soy: templates exist to abstract the intermix of languages. =)
    Imagine you have to do this:
    Hello Mr(s) document.write(sUsername);!
    It’s much moe better to build a template that does the hard job to you.

    Erik: I really enjoyed the idea… if possible, I wanna try to help you. But… I think you should change the syntax (not use the JSP!). If a page is written using Java Server Pages, it could crash and return weird errors.
    Have you thought to use your own syntax… for example… instead of , why do not build as this:

    ASP and JSP uses , PHP uses , CF (I don’t know what the heel this language uses, but you could create your own: . You should probably don’t break any other existent technology by displaying weird errors on screen.

    That’s it… contact me if you need some help.

    Cheers,

  • http://erik.eae.net Erik Arvidsson

    soy: Templates actually fit very well in the concept of MVC. The template is the view. It is a problem when you cannot seperate the view and model but templates, if used correctly helps separate them. Given the following two views. Which is easier?

    http://erik.eae.net/playground/este/tunagetemplate.txt
    http://erik.eae.net/playground/tunage/tunage-text.js

    … now that I look at them with comparison in mind I think the pure js one is nicer. There should have been a nicer writer interface but besides from that the js solution is good. However, I do believe there are places where templates are useful (and it was quite fun to write).

    Guilherme: I agree the syntax is a bit ugly but switching from <% %> to ${ } does not cut it for me. And adding specific structurers like ${for foo in hash} … ${/for} requires a new language. I like the fact that it is still js being used and not another markup to reinvent the wheel.

  • http://ajax-pages.sourceforge.net/ Gustavo Amigo

    Hi,

    that’s so cool, i had exactly the same ideas and feelings recently that i created a project on sourceforge for that. It’s called Ajax Pages. I’ve done a first implementation and i got some good examples. Here is the url:
    http://ajax-pages.sourceforge.net/

    Let’s talk about it better, i really think we can join forces and make a great tool for Ajax developers.

    Thanks,
    Gustavo Amigo

  • http://erik.eae.net Erik Arvidsson

    Gustavo: I think you’ll notice that ESTE is a lot faster than AjaxPages. The main reason for this is that you are using += and I’m using a text writer (array push). When you do string manipulation of this calibre you really must not use += because it is very slow (not only in JS, it is also very slow in Java and C#).

    ESTE currently does not have a license but I’m willing to make it MIT if you want to reuse some code from there. I’ll be happy to help you out here.

  • http://ajax-pages.sourceforge.net/ Gustavo Amigo

    Hi Erik,

    Thanks for the reply.

    I´ll change the code to use the text writer instead of +=. The code i realesed is just a start, kind of a proof of concept. I developed it locally, when i uploaded to Sourceforge, i found that there are many issues that should be treated better. ESTE is faster not only because of the way it treats string, but because Ajax Pages is using XMLHtttpRequest the wrong way, it should be used assyncronous and i am making syncronous calls to the server which makes the browser hang a little bit and makes thins slower. I´ll look at your code carefully to see if i can reuse something or make some parts of Ajax Pages´ code better.

    Steve Yen from JST Templates gave an idea which i think is good. He thinks that a solution for a JavaScript Template should be unique, standard. We shouldn´t have a 100 alternatives to the same problem. I agree with him, if you help we can certanly make that a reality.
    http://trimpath.com/forum/viewtopic.php?pid=373#p373

    I´ve set up a developers mailing list on sourceforge, i´d be glad if you join it.
    http://lists.sourceforge.net/lists/listinfo/ajax-pages-developers

    Thanks again,
    Gustavo Amigo
    gustavo.amigo (@) gmail.com

  • jiming

    I’d like to have a feature to support server side.

    For example, i can put a java object into template and the code in template can access its content, just like Rhino supported.

    Thanks

  • Daniel LaLiberte

    A couple years ago, I prototyped an XML-JS based template system which runs entirely in the browser, but could also be precompiled and run in the server if the data is known at that time.

    The main idea is that a template is an XML document, and every nested { … } is a JS expression. This applies recursively, so that any nested XML elements inside the JS expression are output as text. This results in a very simple and elegant syntax. One complication is use of and & in the JS expressions. For example:

    {
    for (var i = 0; i != rows.length; i++)

    {
    var row = rows[i];
    for (var j = 0; j != row.length; j++)

    { row[j] }

    }

    }

  • Daniel LaLiberte

    Dang.. this blog doesnt encode your postings, or preserve whitespace, so my example was screwed up. There should be TABLE TR and TD elements in the appropriate places.

  • Theodor Zoulias

    Some news about JavaScript Templates. :)
    There is an alternate implementation available, optimized for speed:
    http://trimpath.com/forum/viewtopic.php?id=155

    There are also some instructions to transfer processing server-side, with JScript.NET:
    http://trimpath.com/forum/viewtopic.php?id=150

  • troels

    Since javascript is happening in a browser anyway (or atleast for most purposes it is), we would normally have access to a xslt processor of one kind or another. Wouldn’t it be more befitting to use this as a template-engine instead ?

  • http://blog.netbeans.jp/roller/page/fchoong David Fu

    Hi Erik,
    Firecat is a Server-Side JavaScript Webserver which uses to delimit the start and end of Server-Side JavaScript. So this will probably not mix too well…

    http://firecat.nihonsoft.org

  • Michael Mathews

    Would you consider releasing este.js under a LGPL license Erik?

  • http://erik.eae.net Erik Arvidsson

    I can do ASL2 if that is sufficient?

  • Michael Mathews

    You mean http://www.opensource.org/licenses/apache2.0.html ? That’s cool. I’d like to distribute your templating engine with the JSDoc tool, starting with version 2.0, which is currently under development.

    If you have no objections and agree to apply an Apache License v2, I’ll happily add your stuff to our code!

  • http://erik.eae.net Erik Arvidsson

    I added the Apache Software License header and cleaned up the JSDoc a bit.

  • Pingback: Paul Wilson()

  • Pingback: klus gigant()