Ecma Script Template Engine
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.
May 27th, 2005 at 2:22
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 :-\.
May 27th, 2005 at 4:09
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,
May 27th, 2005 at 10:13
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.
July 29th, 2005 at 5:21
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
July 29th, 2005 at 11:03
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.
July 29th, 2005 at 15:14
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
September 20th, 2005 at 6:03
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
September 27th, 2005 at 16:08
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] }
}
}
September 27th, 2005 at 16:10
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.
October 9th, 2005 at 0:33
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
January 16th, 2006 at 13:37
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 ?
February 16th, 2006 at 5:28
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
November 1st, 2006 at 15:33
Would you consider releasing este.js under a LGPL license Erik?
November 1st, 2006 at 23:34
I can do ASL2 if that is sufficient?
November 2nd, 2006 at 9:36
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!
November 3rd, 2006 at 0:34
I added the Apache Software License header and cleaned up the JSDoc a bit.
December 5th, 2006 at 2:27
Elizabeth Phillips…
The 9169 Donald Lewis blog…