jQuery Template Markup Langauge (JTML) vs. jQuery Templates
Yesterday, jQuery announced the official adoption of the Microsoft-proposed templating library into their core set of supported and endorsed plugins. I've looked at the proposed template plugin in the past; however, now that it is officially endorsed by jQuery, I figured it was time to dig a little deeper and see what I can learn from it. And, perhaps to see what kind of goodness I might be able to bring over into my own jQuery Template Markup Language (JTML) plugin.
I haven't yet reviewed the entire set of features provided by the jQuery Templates plugin; but, even at a cursory glance, it is clearly a very robust and well thought out library. With a good mix of caching and just-in-time compiling, the jQuery Templates plugin provides a good deal of flexibility to suite a wide range of needs.
That said, I'm curios to see a little side-by-side comparison as to how the two templating libraries work. In the following demo, I have borrowed an example from Rey Bango's blog and augmented it with a JTML portion.
<!DOCTYPE html>
<html>
<head>
<title>jQuery Template Markup Language (JTML) vs. jQuery Templates</title>
<!-- Include core jQuery, jQuery Templates, and JTML. -->
<script type="text/javascript" src="./jquery-1.4.2.js"></script>
<script type="text/javascript" src="./jquery.tmpl.js"></script>
<script type="text/javascript" src="./jquery.jtml.js"></script>
<!--
Define the data that we are going to use to render both
sets of templates (jQuery template and jQuery Template
Markup Language). They can both use the same data structure.
-->
<script type="text/javascript">
var clients = [
{
id: 1,
name: "Sarah",
age: 32,
phone: [ "917-555-1234", "212-555-1943" ]
},
{
id: 2,
name: "Maggie",
age: 25,
phone: [ "917-555-8989", "646-555-0001" ]
},
{
id: 3,
name: "Emma",
age: 27,
phone: [ "212-555-3999", "508-555-1492" ]
}
];
</script>
</head>
<body>
<h1>
jQuery Template Markup Language (JTML) vs. jQuery Templates
</h1>
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- jQuery Templates. - - - - - - - - - - - - - - - - - -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<h2>
jQuery Templates Example
</h2>
<div id="jqtOutput">
<!-- This will be filled dynamically. -->
</div>
<script id="clientTemplate" type="text/html">
<p>
<a href="clients/${id}">${name} - Age: ${age}</a>
</p>
{{tmpl( $data ) "#phoneTemplate"}}
</script>
<script id="phoneTemplate" type="text/html">
<ul>
{{each phone}}
<li>
${$value}
</li>
{{/each}}
</ul>
</script>
<!-- Execute template. -->
<script type="text/javascript">
$( "#clientTemplate" )
.tmpl( clients )
.appendTo( "#jqtOutput" )
;
</script>
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- jQuery Template Markup Language. - - - - - - - - - --->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<h2>
jQuery Template Markup Language (JTML) Example
</h2>
<div id="jtmlOutput">
<!-- This will be filled dynamically. -->
</div>
<script id="clientTemplate2" type="text/jtml">
<jtml:loop index="client" collection="clients">
<p>
<a href="clients/${client.id}">
${client.name} - Age: ${client.age}
</a>
</p>
<jtml:include template="#phoneTemplate2" />
</jtml:loop>
</script>
<script id="phoneTemplate2" type="text/jtml">
<ul>
<jtml:loop index="phone" collection="client.phone">
<li>
${phone}
</li>
</jtml:loop>
</ul>
</script>
<!-- Execute template. -->
<script type="text/javascript">
$( "#jtmlOutput" ).html(
(new JTMLTemplate( $( "#clientTemplate2" ) )).render(
{ clients: clients }
)
);
</script>
</body>
</html>
As you can see above, we have a clients collection with three clients, each of which is defined by an id, name, age, and set of phone numbers. This client list is then rendered as HTML using the jQuery Templates plugin followed by the jQuery Template Markup Langauge (JTML) plugin. When we run the above code, we get the following output:
Clearly, both templating plugins are capable of producing the same output (at least in this example); however, the underlying markup is quite different. The jQuery Templates plugin allows for very terse markup and provides a number of defaulted values. JTML, on the other hand, is notably more verbose and provides no defaulting whatsoever (well, technically it does provide defaults, but not in any documented way).
jQuery Templates also makes some assumptions about the kind of data being passed-in and about how that data is going to be treated. That's because jQuery Templates is very much optimized for implicit action. JTML, on the other hand, makes no assumptions about the data being passed-in and requires explicit actions to be taken on all data points; JTML's initial concern is only with setting up a context for execution, but takes no steps towards making any particular actions happen.
NOTE: As an aside, neither of these demos actually needs two tempaltes; both jQuery Templates and JTML are both capable of performing deep nesting within a single template.
I am sure many people will look at the JTML and shutter at its tag-based implementation; however, coming from a ColdFusion background, this style of templating feels much more natural than a mixture of scripts and tags. I wouldn't say that one style is better than the other - this is simply what I am used to after 10 years of CFML usage.
As application logic starts to move to the client-side of the request-response life-cycle, Javascript-based templating is going to become more and more important in our daily lives. I am very excited to see jQuery officially adopt a library that will continue to grow and improve with time. jQuery Templates looks to be very robust and will require a lot more investigation on my part. At this time, however, I don't think that I'm quire ready to abandon JTML as I do like a lot of the features it has. In the future, I'll have to see whether it's worth growing, or if I should just go whole-hog into jQuery Templates.
Want to use code from this post? Check out the license.
Reader Comments
@Ben,
I'm starting to see server-side templating (CFML) and client-side templating as complementary, much like server-side and client-side data validation. Because JavaScript could be turned off, you can't rely solely on client-side templating or data validation, so you fall back to server-side equivalents.
It's been easy in the past to ignore client-side templating on the grounds that "damn, I have to do it in ColdFusion too, so what's the point?" But Offline Web Apps are changing that. As we plan to make our apps accessible even when the Internet isn't, we still have the problem of repeating chunks of HTML, but no ColdFusion on the client to help us do it.
You favor a tag base approach because of the similarity to ColdFusion. John Resig's original "microtemplating" article took a tag based approach too. He was the one who came up with the idea of using script tags with type="text/html" to define the template. So your preference has good foundation, right back to the very beginnings of JavaScript templating.
Steve, while you make good points, I disagree with you on one point. Falling back to server side templating when javascript is turned off client side. At this point the web is pretty much useless without javascript and I don't think at this point is reasonable to acquiesce to stubborn users. I view disabling javascript much like, disabling cookies. If you don't turn it on then I won't play with you. There is just so much done with js these days there really isn't a good reason to disable it in the browser.
@Steve,
I also see client-side and server-side templating as being complementary in that I think there are situations in which both of them make sense. I think that ultimately, all template could be done server-side; and, when ColdFusion makes that so easy, it's definitely tempting to return HTML instead of JSON for AJAX requests (and there's nothing wrong with that - I think we all do that).
@Chris,
I am inclined to agree that using server-side templating as a fallback is probably gonna be more trouble than it's worth. Honestly, I'm not a huge follower of progressive enhancement; and, in big applications, I think there is nothing wrong with imposing "application requirements."
An interesting side-by-side. I've been using the proposed MS template plugin, and it has worked great for me.
Integration with the jQ data linking plug-in (including 2-way) is another benefit of using the official jQ template plug-in.
http://weblogs.asp.net/scottgu/archive/2010/05/07/jquery-templates-and-data-linking-and-microsoft-contributing-to-jquery.aspx
Since I'm doing a lot more javascript these days I've come to like script based syntax more than tag based. Ditto for CF - I prefer to use cfscript where I can.
If JS is disabled (whether you like it or not) will the JS tags shopw up in the page?
For example, would the line:
{{tmpl( $data ) "#phoneTemplate"}}
Show up on the page as literal text if I disabled JS? If so then this could be mighty ugly and mess with SEO.
I literally only just heard about this from your post so please do bare with me on my ignorence!
@Adam,
I think there's definitely a lot that is good about them. The functionality seems pretty rich - well work a deeper exploration.
@Johans,
Script vs. Tags is definitely something that is almost entirely personal. ColdFusion gets compiled - Javascript templates get "compiled" to re-usable functions; so it's not a performance thing, just a preference thing.
As far as data-linking, I'm not sure how I feel about this technology just yet. I like the idea of event pub/sub approaches. Part of me feels that data-value-specific binding seems overkill, and in some ways, a breach of encapsulation. I'll definitely look into it more though as I don't fully know the benefits yet.
@Unibands,
The script tags will not show up in any case. Since they do not have a standard Javascript type "text/javascript", the browser essentially ignores them as far as rendering goes.
Nice work, Ben! Many thanks for your continuing explorations.
@Hal,
Thanks Hal - I'll follow up with some of the jQuery Templates features.
finally got around to playing with both this example and the nettuts one on the 'official' plugin
i'd say i agree with your general comment that it is a matter of personal preference between the two approaches
have you looked at how the two perform for larger datasets, or is the main bottleneck the data fetching call?
with a bit of time next week i'll try to migrate some messy inline js templates i've inherited to your plugin instead - at least on the dev version :D
@Atle,
I think under the hood, all of the templating approaches use a very similar technique - "compiling" the markup into an executable function. As such, I would assume that they all have similar performance concerns... of course, this is just a guess.
I do really want to look into the official templating more though; there's a lot of functionality I have yet to even touch on.
Sort of wish I found this a little earlier! I actually created a plugin for jQuery called json2html which is sort of a templating engine for jQuery, however it's based more along the lines of a transform (similar to xsl transforms for xml). The idea is to use a JSON object transform to convert another JSON source data object into HTML.
I've used this in a number of projects and it works extremely well. It is DOM dependent and does include support for event binding etc.. The nice thing about the library is that everything is JSON, pure javascript implementation that creates HTML markup using the DOM.
The drawbacks are as follows:
a) it's limited to creating an unstructured list at the highest level of the DOM produced
b) creating transforms in JSON takes a little while to get used to
The benefits are as follows:
a) very lightweight 3Kb
b) recursive in nature (making it extremely flexible). Including transform 'nesting'
c) completely based on the DOM with appropriate event creation
Here is an example for using JSON2HTML for the client example above
Source code and examples can be found here
www.json2html.com
Also the following site's include this plug-in
www.new2release.com (heavily dependent on JSON2HTML)
www.projectclimb.com (search functionality)
thanks for your source code and examples. it's really useful.