A few thoughts on jQuery templating with jQuery.tmpl
General, JavaScript, jQuery, UI By Dave Ward. Updated November 8, 2010I spent some quality time with Dave Reed’s latest revision of John Resig’s jQuery.tmpl plugin recently, migrating a small project from jTemplates. Since both the jQuery team and Microsoft team have requested feedback on jQuery.tmpl, I decided to write about my experience using it (as I am wont to do with these templating proposals).
Overall, jQuery.tmpl is a great step in the right direction. It’s small, it’s simple, and it’s fast. Overloading append() to allow the append(Template, Data) syntax is phenomenal. That approach feels more like idiomatic jQuery than anything else I’ve used, including jTemplates.
However, if this template rendering engine is going to succeed broadly, I feel there’s one important feature still missing. Additionally, there are a couple ancillary features that are present in the current proposal, but should be protected.
Composition
One area where jTemplates still comes out on top is template composition – also known as nested templates. Specifically, this refers to the ability for templates to contain references to other templates, and the ability to render that entire group as a whole.
The need for template composition may be hard to see in simple examples, but most non-trivial scenarios benefit from template composition. Dave mentioned the example of having a person template that embeds a separate template for displaying information on one or more phone entries about those person records.
That’s a good example, but take it one more step to understand where composition really shines. Consider the possibility that each of those phone records has a type (e.g. Mobile, Home, or Work) and that each type must be presented with different markup.
Template composition provides a clean solution to this problem. By creating separate templates for each type and then rendering the correct amalgamation of those templates, the template code remains simple (but is powerful).
A composition workaround in jQuery.tmpl
Currently, something resembling nested item templates are technically possible via the each keyword in jQuery.tmpl, but it’s not pretty. This example from the jQuery.tmpl demo illustrates that approach:
// Data cities: [ "Boston, MA", "San Francisco, CA" ] // Template Cities: {{each(i,city) cities}}${city}{{/each}}
Even for this most simple case, the syntax is rough. Not the sort of readable simplicity that we’ve come to expect from jQuery.
More importantly, extending that to conditionally render different fragments of markup would be much more difficult.
A cleaner workaround (but it’s a trap!)
The jQuery.tmpl demo also contains this seemingly elegant alternative:
// Data cityJoin: function() { return this.cities.join(", "); }, cities: [ "Boston, MA", "San Francisco, CA" ]
By embedding a function in the data, referencing that object key in a template returns the result of the cityJoin function. Thus, jQuery.tmpl renders the function’s result, not the function declaration’s actual text.
That technique dramatically simplifies the template itself:
// Template Cities: ${cityJoin}
While that approach does succeed in avoiding the messy template code that each requires, it tightly couples concerns which should not be.
When this is put into practical use, the data object will usually be requested from the server-side. Would my business logic or data repository tier need to inject the joining function? I don’t think I could bring myself to do that.
Further, it doesn’t really address the real-world scenarios I’ve encountered. A callback function to format data won’t feasibly scale to rendering heterogeneous chunks of markup. Effectively, it’s the same as the each solution, with the pain point shuffled around a bit.
How I think it should work
As long as there’s some way to name and render sub-templates, I don’t care how exactly it works.
I wasn’t crazy about jTemplates’ {#include} syntax at first, but it’s okay once you get used to it. Most any syntax shouldn’t be difficult to learn and acclimate to.
Since jQuery.tmpl already provides for caching the templates in jQuery.templates, all that’s really necessary is a method for rendering those named templates within other templates.
A concrete example
This example simplified a bit, but is functionally similar to client work I come across regularly. To be clear, this is something I’m currently using today, not something I’m just theorizing as a good idea.
I want to be able to take data that isn’t necessarily homogeneously structured:
{InvoiceItems: [ { ItemType: 'Product', PartNumber: '99-Designs-Logo', Description: '99 Designs Logo design', TotalCost: 450 }, { ItemType: 'Service', DescriptionOfWork: "Website development", TotalCost: 5000 }, { ItemType: 'Service', DescriptionOfWork: "Deployment and testing", TotalCost: 300 } ])
And use a set of templates like this to render that data (did I get the each syntax right in #Invoice?):
{#ServiceItem}
<tr>
<td colspan="2">{$DescriptionOfWork}</td>
<td>{$TotalCost}</td>
</tr>
{#ProductItem}
<tr>
<td>{$PartNumber}</td>
<td>{$Description}</td>
<td>{$TotalCost}</td>
</tr>
{#Invoice}
<table>
<-- Fancy thead here -->
{{each(i, InvoiceItem) InvoiceItems}}
{{if $InvoiceItem.ItemType === 'Service'}}
{{render('ServiceItem', InvoiceItem)}}
{{else}}
{{render('ProductItem', InvoiceItem)}}
{{/if}}
{{/each}}
</table>Scenarios just like that one are common in my current work with jTemplates. Imagine trying to implement that with each or an embedded callback function.
Now imagine you wanted to conditionally render those same row templates as sub-items in more than one master template (e.g. maybe there’s also a credit memo template similar to the invoice, but not identical). The burden of maintaining an application like that quickly compounds without template composition.
Again, the exact syntax doesn’t matter. Any implementation that provides the functionality would be a win.
External templates
I’ve never understood the desire to cruft up a page with inline templates. Whether they’re hidden through CSS or embedded within a text/html type script element, cluttering my markup with templates feels sloppy.
jTemplates introduced me to the idea of storing templates externally, and then asynchronously loading them only as necessary (example). I adopted that approach at nearly the same time I began using jTemplates and haven’t looked back since.
My affinity for remotely template loading caused me to lobby for remote templates both in the DataView and more recently in jQuery.tmpl. However, what I hadn’t considered is that it’s already easy to load external templates with jQuery’s built in AJAX functionality. With the template loaded into a string variable, the append(TemplateString, Data) syntax connects the dots perfectly.
All of that is simply to say: Please do leave the append(TemplateString, Data) syntax intact. As long as we can provide templates via string variable, built in remote template loading isn’t necessary.
On the need for in-template logic
I’ve heard some dissention on the issue of conditional logic within templates.
Philosophically, I agree; mingling logic into your presentation/view is dangerous. It’s always a slippery slope, at best. However, the pragmatist in me ultimately cannot agree with the hard-line approach of banishing it completely.
A project I’m working on is a good example. My client-side code must display a collection of invoices sourced from a legacy backend, each with an upgrade number. Upgrade 0 must be displayed as “Original Invoice”, but the rest should be displayed as “Upgrade n”.
A conditional in the template makes quick work of the problem (this is jTemplates syntax, not jQuery.tmpl):
{#if $T.Upgrade == 0} Original Invoice {#else} Upgrade #{$T.Upgrade} {#/if}
Since it’s purely presentational logic, it belongs in the template as much as it does anywhere. Please do keep that functionality available, even if it does have potential for abuse.
In addition to the currently available conditional keywords if and else, elseif and switch would both be nice additions.
Conclusion
Overall, I’m excited about the potential of seeing jQuery.tmpl integrated into jQuery core, or even made available as an “official” plugin. As much as I like jTemplates, support and documentation for it is spotty at best.
Ultimately, we will all benefit from standardizing on an official templating solution rolled into the jQuery core, rather than each of us using our obscure favorite.
I’m curious what you think. Am I the only one using template composition? Anyone want to make a convincing case against conditional logic in templates?
Similar posts
What do you think?
I appreciate all of your comments, but please try to stay on topic. If you have a question unrelated to this post, I recommend posting on the ASP.NET forums or Stack Overflow instead.
If you're replying to another comment, use the threading feature by clicking "Reply to this comment" before submitting your own.
2 Mentions Elsewhere
- Tweets that mention A few thoughts on jQuery templating with jQuery.tmpl | Encosia -- Topsy.com
- 網站製作學習誌 » [Web] 連結分享



Hey Dave,
Have you tried Pure (http://beebole.com/pure/)? Wondering what your opinion is if you have.
I’ve looked at PURE a few times, superficially, but I haven’t used it enough to form a solid opinion either way.
If they get templating added to jQuery core in 1.5 (and add composition), a third party templating library would have to be pretty compelling to justify including on top of what would already be available.
Excellent write-up, and I just have one question for you. Why exactly do you think it is bad to have templates inline with the page? It seems to me that unless you are sharing your templates across pages (which is likely), that having the template in the page along with the html that it is going to be used with, would be beneficial.
Now, I could certainly imagine a site that is so chopped up with views and master pages, and whatnot that you don’t have a good place to put the views, but even then it would seem that having them grouped somewhere and not loading them one by one would be a better solution.
Thoughts?
Sharing is one reason (and effective caching, as a corollary).
Another reason is that the templates become somewhat large once you’ve built them out for real usage, but you may not want to render them immediately – or even at all – depending on what the user does. It’s nice to be able to defer loading and get a faster initial page load, rather than pre-loading every possible template for a page.
Another issue is SEO. On public facing sites, I’d rather the search engines index nothing at all for templated regions than index a pre-rendered template. Better that I can let them focus on indexing the static content than try to parse the semantic meaning of the crunchy un-rendered template syntax.
To mitigate that a bit, I do try to group them in single files where it makes sense. In the example of the invoice and its various row templates, I would keep them all together in one file rather than have several HTTP requests to get each fragment.
Hi Dave, you got me started with jQuery templating, and I’m loving it. One thing I’d love to see with the jQuery.tmpl / MS collaboration is a way to use the js template to render data server-side. I know you can just populate the data when the page loads, but I’d like to do it server-side in case the client doesn’t have js enabled. Maybe you know of a way to do that already? I’m tired of having a template and then page layout that mimics the template.
If you’re using MVC, there’s an option I know of: Spark. It’s primarily a server-side view engine for MVC, but also has the (less documented) ability to generate a JavaScript version of any of those server-side templates. Those JavaScript-ized templates are able to take JSON data and render the same template on the client-side that would have rendered on the server-side via the ViewData.
K. Scott has a writeup about that functionality here, if you’re interested: http://odetocode.com/blogs/scott/archive/2009/03/12/client-rendering-views-with-spark-and-asp-net-mvc.aspx
I don’t know of something similar for WebForms (yet). I believe they’re aware of the problem and working on some solutions though.
I’m totally with you on the deferred loading of templates, Dave. I’m completely against cluttering up HTML with inline script, template code, or anything else for that matter. That sort of thing belongs external, as it doesn’t have any semantic meaning in the context of the page.
Thanks for the writeup.
@Dave, PURE is a library to transform JSON to HTML, not only with jQuery.
And is very different from the usual smarty/ASP/JSP like logic, where logic and view are mixed.
Here are some differentiators:
- a total separation between the HTML representation and the JS logic
- PURE works with most common JS libs. Or stand alone on modern browsers
- for the mobile web, pure.js is only 8kb and can be used to render all the HTML of a site without any heavy JS libs
- the template logic is live(not stringified, not evaled). It means that we can use closures at rendering time
We launch our app next week, it will be a good show case of the speed a web app can have, and what can be done with PURE.
Thanks @Tyler for the link.
Resig has improved his original tmpl library as well. It’s a little lighter than the Microsoft solution, but I’ve found it to be just as capable. I’ve found it very easy to extend, and I’ve been able to add in some of the MS features like nested templates and full count of the data array without touching the core plugin. You should give it a test run as well.
Does your “partial” approach work with templates defined as string variables, or does it require the template be embedded on-page in a script element?
Yeah, it really is just adding a recursive call back to render(), so you can expect to work with a {{partial}} just like you would work with any normal tmpl template. All of the tmplcmd’s are available and the ${this} and iterator($i) are scoped to the JSON you pass through.
So, my example over on the jquery forum could be written as
{{partial('${this}') cities}}Also, the tmpl plugin doesn’t require that the DOM element be a script. script is just a way to keep the markup out of the display.
Whoops. Looks like my code didn’t go through. There should have been li tags surrounding the
FYI — I updated the {{partial}} command. It can now use pre-built templates and has access to the $data from its parent template.
A superb critique, which eloquently details a number of issues that I have been concerned about but not seen covered elsewhere.
The only point on which I differ in opinion is that to me the need to separate and reuse template HTML code is pretty critical and surely such a common requirement that it merits having external template loading functionality built into the plugin from the word go, rather than having developers roll their own solutions. I would want to be able to specify one or more external template files, each of which would be a skeleton HTML document containing one or more templates.
The thought has also occurred that if these templates were embedded into these HTML template master documents inside SPAN or DIV elements instead of SCRIPT or STYLE then the files could be authored in a WYSIWYG editor like Dreamweaver of Eclipse, and if CSS were included in the document as usual then they could even be viewed/edited/styled exactly as they would appear when the templates are rendered in use.
Without this WYIWYG editing ability (which we take for granted nowadays but the current proposal simply doesn’t allow for) I think that complex templates will prove to be very time-consuming and error prone to construct and style, especially during an iterative design process, or when making changes to a live app.
What do you think?
And have you had a response from JResig or anyone else on the jQuery team regarding your post?
The external loading is trivially easy (as in one line of JavaScript, if you don’t mind a blocking load), so don’t worry about that. I’ll post a tutorial on how to do that, assuming it doesn’t end up in the final iteration.
Regarding visual editors, I don’t use them enough to have a useful opinion. My experience with compound jTemplates templates has been a good one though. With decent naming and commenting, they’ve remained very maintainable for me over the past year or so.
I don’t know about John, but the Microsoft guys that are contributing to jQuery.tmpl did see this.
@Markus
PURE keeps the HTML totally clean and separate from the JS logic.
And you can load the HTML templates either by an ajax call or by an iframe.
Did you try it?
Hi! Very interesting post.
I wanted to read a lot before choosing a template engine for javascript.
I have seen the Spark website I think their idea is great,
Actually I have a View class just like Smarty, I think I could do the same that spark does and having an option to export the View to Javascript / HTML instead of PHP / HTML, I think this approach is very good because justs like Walt comments there’s no need to duplicate templates, but, also, there’s no need to use two template engines or to learn two template languages.
@Mic – PURE looks awesome, thanks for bringing it to my attention, I’ll look forward to using it when I redevelop my photography portfolio site…
great post, my main concern however, is that for newbies to templates like me, your post is a bit confusing. Are saying that jQuery templates are not there yet so continue using the jTemplate library. you forced me to look at the jTemplate lib vs the jQuery lib and I find that I understand jTemplate better. I’m working on a web application for the iPhone, iTouch or anything that uses the web-kit. this application uses tons of s (over 100 in one case)to handle the ui interface and i’ve been looking for a way to cut the cost of the code down and i thing the jTemplate is it because they are very repetitive and for each square of 50px by 50px there up to six hot spots inside each square. the functionality is the same but the conents differ slightly in each square. the application also uses a lot composition where there dependencies inside dependencies which it looks like jTemplates could handle better and easier. anywho: i’ll keep u posted on my progress..
Thanks for the post it was a great learning experience and i did follow all of the links…
At this point, I would definitely recommend using jQuery Templates instead of jTemplates. jTemplates is fine, but can’t match the level of community support and development efforts surrounding the “official” API. Maybe more importantly for a mobile app, you’ll get jQuery Templates for free in jQuery 1.5, included in the core library.
Hi Dave, have you found a way to implement your idea of templating a collection of objects?
I’ve been searching for the same idea few hours with no luck!
Thanks
This post describes how I ended up approaching composition with jQuery Templates: http://encosia.com/composition-with-jquery-templates-why-and-how/
Thanks for the link. I am worried when dealing with jQuery templates on Localization of Forms & unobstrusive validation that I get out of the box when I used MVC Views.
Can a template also ensure localization and validation function properly as if content is placed inside a View?
Thanks