Its a long time I miss publishing something interesting (ok, actually, publishing at all!) but this is for two good reasons:
one – I was really involved on Licorize development
two – I spent one month on holidays in Iceland
three – this is the kind of blog-post that may attract lots of spit
I’m little squeamish, and I tried to delay this moment as much as I can, but Licorize beta is now available and I’ve returned happy, alive and healthy from Iceland.
Damn! I cannot procrastinate any longer.
This history started about two years ago when I found the John Resig micro-templating paper; John’s idea was intriguing even if it seemed hardly original: separate presentation and data. This is an old liet motif for many programming-pattern-book-writers, and this is usually enough to worn me to shun away, but in this case something hit me, say because Resig seems a practical fella or say because the <script type=”text/html” > smells of “beautiful hack”. I don’t know why, but micro-templating remains impressed on my mind.
What is a JavaScript template? In brief it is a way to call a JavaScript function for injecting dynamically html contents client side.
The simplest usage could look like this:
var data={id:1,description:”my item”,price:”123.45”};
var place= document.getElementById(“results”);
results.innerHTML = template(“item_row”, data);
For web 2.0 applications this is a really powerful approach to page generation: send templates to clients, use JSON for communicating with the server, generate contents using templates+data and create the fastest applications you have ever seen! If you add the great support jQuery offers for JSON, this could be a really nice solution.
I didn’t get deep into Resig’ solution at the time, but I kept the JavaScript templating idea in a closet for a while, until last April when I started working on Licorize.
Licorize is an empowered bookmarking system that allows collecting to-dos, ideas, images and much more while you are working on-line, and then organize your work in team. But for the moment what is interesting is that Licorize uses small pieces of html to represent information on a sorted list. Here an example:
The main Licorize requirement was to be a fast web 2.0 application: to me this means use one page only. I know that is not completely true, but coming from a “classical” background of Java-JSP developer, it was a revolutionary approach.
I then recalled the JavaScript templating idea, and started programming around.
A short googling on “javascript templating” left me astonished about the number of JavaScript frameworks already available, so I started trying some of them.
Before you, dear reader, read more I warn that this is the hard core part, if you believe emacs is the best editor for writing web-apps or you think the XML-XSLT is the cleanest approach to produce html pages, leave before its too late! What you will see below is an approach that searches to maximize compatibility of writing code, also HTML, with an IDE.
Ok, so lets me state some of my personal principles concerning programming:
-
a simple rough solution is far better than a powerful but complex one
-
it is incredible stupid to invent new languages/tag/whatever while the existing ones work just fine
-
your designer’s work worth as much as your “dirty code”
-
you cannot nowadays write code without a decent IDE, or better: you cannot write decent code without a great IDE! This is why I use IntelliJ!
-
every trick is legal if it makes your life easier (not only writing code
)
Taking in mind these points I started exploring the JavaScript template galaxy.
Starting from Resig’s example I noticed that the suggested syntax generates confusion when you use a .jsp to generate the “template” page. JSP standard tags are also used for defining JavaScript variable placeholders:
Actually the following code, from Resig’s example, generates panic in most JSP coders (Example 1):
<script type=”text/html” id=”user_tmpl”>
<% for ( var i = 0; i < users.length; i++ ) { %>
<li><a href=”<%=users[i].url%>”><%=users[i].name%></a></li>
<% } %>
</script>
here “users[i]” is a JavaScript variable not a JSP one!
If you think that generating templates using dynamic pages is useless you are on the wrong path, in good company with those that think that out.print(“<%=users[i].url%>”) could be an acceptable price to pay for using templating – no way!
Analyzing this example I found that is not strictly necessary to have iteration or conditional support in the template definition language: you can narrow the scope of templates and use JavaScript for doing iteration. With this approach you gain flexibility and you do not need strange syntax. See the code above transformed (Example 2):
<script type=”text/html” id=”user_tmpl”>
<li><a href=”<%=users.url%>”><%=users.name%></a></li>
</script><script type=”text/javascript”>
…
for ( var i = 0; i < users.length; i++ ) {
template(“user_tmpl”,users[i]);
}
</script>
The code is a little bit longer, but more readable and flexible (e.g.: if you need to use a different row template in function of user data).
What in Resig’ approach is in the right direction is that the template is mainly written in html, that means that templates can be created by UI guys, using (almost) standard html tags.
If you believe that this is the most obvious approach, and that everybody would start with this, you are wrong: there are lots of libraries where the template is created with “string concatenation”.
Seems peculiar to me that library writers are mostly focused on implementing “for”, “if”, “while” statements inside templates instead of making it easy to write them down. Why they want to waste its time implementing (badly) something already happily existing in JavaScript?
In this category mustache.js , Tempest or nano, but the list is far from being exhaustive.
Some other libraries have the sensibility to propose a way to write html in a more comfortable way; usually they use the trick of “<script type=’text/…..’>” tag, as proposed by Resig or a in a mixed way with “<
The pre-compilation piece is where I too deviated from Resig’s idea. I personally find it much better to pre-compile to 100% pure JavaScript. Then the template itself is just another script which can be combined with other scripts, lazy loaded, etc.
A few years back I was trying to solve similar problems and implemented JBST (JsonML + Browser-Side Templates) (see http://jbst.net and http://jsonml.org/jbst ). It is templating extensions on top of JsonML, the syntax for representing XML markup in JSON (see http://jsonml.org ). The idea being that an ASP/JSP-style template is parsed *at build time* and lives as a JavaScript tree at runtime.
Perhaps the JBST serialization format would be useful for you as well. Technically it doesn’t really care what the syntax of the original template is.
The compilation system itself is currently only built for .NET as a part of JsonFx (see http://starterkit.jsonfx.net/jbst). It is extremely fast. I’m currently building v2.0 which adds server-side execution of JBST templates (see http://github.com/jsonfx/jsonfx-ui ), but again it is written in C#.
I’ve just finished the implementation of pre-compilation in Resig’s style.
Now my template-engine supports both syntax “##”, “(#=” and “(#”. So it allows to use statements (even if personally I don't like it). I started from Dan Wahlin’s example here.
I did some performance test with a simple template, using FF and Chrome, but I didn't report drastic differences between pre-compiled and plain ones; the difference generating 10.000 blocks was less than 5%, in absolutes values about 80 ms on 2 secs.
But I reported a significant difference increasing the template complexity and the number of blocks. Pre-compiled ones are faster than plain ones of a big 70%.
In both cases FF seems at least, jaded.
So, for a reasonable amount of blocks, both methods works fine. If you need to display 10.000 lines choose carefully your browser!
Thank you, for the precious hint.
my Editor (visual studio) adds breaklines between the , and breaks the code of jquery gantt.
how can I adjust the the jquery.JST.js?
You will find the updated files here: https://github.com/robicch/jQueryGantt/tree/master/libs/JST