Rey Bango

Web developer, honey badger

Not Using jQuery JavaScript Templates? You’re Really Missing Out.

In preparation for my upcoming talk on jQuery Templates, I’ve been been deep diving into the jQuery Template plugin created by Microsoft.. Many of you are probably familiar with server-side template engines like Smarty or Cheetah but only recently have client-side template engines taken off. Considering how complex our web apps are becoming, it makes total sense.

The cool thing about templates is that it lets you easily structure your content display without all the hassle of string concatenation. For example, say I had a data set containing an ID and a name and I wanted to display the name as a hyperlink.

I could do something like this:

var clRec = "";

for(var i=0; i<client.name.length; i++) {
    clRec += "<li><a href='clients/"+client.id[i]+"'>" + client.name[i] + "</a></li>";
}

but to me, this seems much more readable and maintainable:

<li><a href="clients/${id}">${name}</a></li>

The second code snippet is a template I’ve created to render a hyperlinked name in a list and it’s very easy to do. First, include both jQuery and the jQuery Template plugin into your page:

<script src="http://code.jquery.com/jquery.min.js" type="text/javascript"></script>
<script src="jquery.tmpl.js" type="text/javascript"></script>  

Next, define the data that you’d like to see rendered. This could be data derived from an XHR call or something you’ve predefined, like this:

	var clientData = [
		{ name: "Rey Bango", id: 1 },
		{ name: "Mark Goldberg", id: 2 },
		{ name: "Jen Statford", id: 3 }
	];

Now, define your template:

<script id="clientTemplate" type="text/html">
	<li><a href="clients/${id}">${name}</a></li>
</script>

Yep, the “script” tags are necessary and used because they allow your template to be embedded within the body of the page. Notice that we’ve defined the placeholders as ${id} & ${name}, the same names used in the identifiers in our data. The “${}” tells the template parser that the field needs to be replaced with the expected value.

Then call the jQuery Template plugin to render the data using your template:

$("#clientTemplate").tmpl(clientData).appendTo( "ul" );

The plugin’s .tmpl() method accepts the data we’ve defined and handles the parsing of the template we’ve selected. Then we use jQuery’s .appendTo() method to append the results to an unordered list tag. This gives me the following results:

That’s it! Told you it was simple. :)

I’ll go into more advanced details during my presentation but this should give you something to start with in the meantime. Here’s the full source for you to use:

<!DOCTYPE html>
<html lang="en">
<head> 
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
  <meta name="robots" content="noindex" /> 
  <title>Template Test</title> 
  <script src="http://code.jquery.com/jquery.min.js" type="text/javascript"></script>
  <script src="jquery.tmpl.js" type="text/javascript"></script>  
  <script type="text/javascript">
  $(document).ready(function() {

	var clientData = [
		{ name: "Rey Bango", id: 1 },
		{ name: "Mark Goldberg", id: 2 },
		{ name: "Jen Statford", id: 3 }
	];


$("#clientTemplate").tmpl(clientData).appendTo( "ul" );


});
  </script>

 <script id="clientTemplate" type="text/html">
	<li><a href="clients/${id}">${name}</a></li>
</script>
  
</head> 
 
<body> 

<ul></ul>

</body> 
</html> 

Category: AJAX, JavaScript, jQuery

Tagged:

76 Responses

  1. Not to sound like your fan boy, but this is the second time you’ve taken a concept I’ve needed to look at and explain it in a simple, direct manner. Thank you. Let me queue up a list of requests so you can tackle em.

    Any objection to me taking this post here (http://www.coldfusionjedi.com/index.cfm/2010/7/9/Another-simple-jQueryColdFusion-example) and modifying it to use templates and posting it?

    • Rey Bango says:

      hehe. Very cool. After many years of being a Ray Camden fanboi, it’s now being turned around. :D

      Of course Ray. I put that code up for anyone to use. Go for it. :)

    • Kernel James says:

      How does that compare to other templating options like Distal code.google.com/p/distal or Mustache mustache.github.com , please do a writeup.

      • Rey Bango says:

        Not really sure since I’ve not used those other libs. As for a writeup, I don’t expect to have time to do one so your best bet is to take what I’ve done and compare all three.

  2. Mr Speaker says:

    I certainly love templates… oh, so many hand-crafted document fragments! Buuut… how the heck did John Resig’s beautiful 20-odd line micro-templating code turn into THAT?!

    • Rey Bango says:

      I haven’t used John’s but note that John is actively providing feedback to the MS team on that plugin and that feedback has been incorporated into the plugin.

      • Mr Speaker says:

        The original templating code was here: http://ejohn.org/blog/javascript-micro-templating/ – someone had put out a fix a “single quote” issue… can’t find it right now. Looks like it’s done a bloat-morph into something huge now – obviously it must contain some better features, but if all you want is to do the templating examples you’ve done in the code above, then the tiny (jQuery-free) solution might be better!

  3. Mark Richman says:

    The owner of this project on GitHub is “nje (.NET jQuery Extensions)”. Is there anything .NET-specific here? This looks like it can be used anywhere.

    • Rey Bango says:

      Nothing .NET specific at all. That’s just the name the Microsoft team chose for their account. They’re working with the jQuery team on these plugins as well and are following the jQuery Project’s contribution guidelines.

  4. I’ve recently blogged about how to use the jQuery Template plugin with Twitter JSON Data.

    http://ralphwhitbeck.com/2010/06/22/UsingJQueryAndTemplatingToPullAndDisplayYourTwitterUpdates.aspx

    • Rey Bango says:

      Yep. That was a very cool use of it. Note that you may want to update the code to use the new .tmpl() method since .render() has been deprecated.

      • Rey is there an official web site for the plugin besides the github repository? It’s hard to keep up with a plugin via each commit.

        Would really like a point release of the plugin that explains what’s changed.

        I did not know they changed render -> tmpl nor would I unless you said something.

  5. Brian Wilpon says:

    Awesome work Rey. Is it possible to put the “text/html” script block in an external file?

    • Rey Bango says:

      Good question. I’m not sure but I’ll look into it.

      • Chris Love says:

        You should be able to add the template block at anytime in the life cycle of your page. However before you use this or the micro-templating engine it must exist to actually work. It would be no different than any other DOM element on the page. The text/html thing is a trick to keep the browsers from evaluating the block as a js block.

    • Justin Meyer says:

      Brian Wilpon,
      It is not possible. This is a huge, and overlooked, problem with most templating solutions. At some point, you don’t want all your templates to be sent inline, just like you don’t want scripts inline.

    • 3rdEden says:

      If the external file is on the same domain, you can just build a small script that search all script[type='text/html'] and pull them in with an AJAX request.

  6. David says:

    The templates are great…but I do see the potential for misuse that I’d like to chime in on. In general, I would say that jquery javascript templates should really only be used for the display of dynamic, non-SEO relevant data, since search engines do not parse javascript.

    I see the temptation, especially in DNN, to rely on client side templating for more than just this type of dynamic data display. For instance, you would not want to use javascript templating on something like Forum posts, or comments on a blog (such as this)…since that is unique and relevant content that has great SEO value.

    Just my 2 cents worth. :)

    • 3rdEden says:

      Depending on your use case, you can also use the data that is already present on your page and feed that in to the template engine. Allowing you to provide a richer experience for those who have JavaScript enable for example ;)

    • Allan says:

      Google now parses javascript on a simple level, and they’re working to broaden their abilities. It’s a recent thing …

    • Chris Love says:

      Great point, I have been contemplating what is the best architecture when it comes to AJAX and SEO needs. behind the firewall, it does not matter so much, but for a public site that needs good positioning you need to make sure the important info is on the page without any AJAX needed to load it IMO.

  7. Jan Hohner says:

    Nice howto Rey! I think this will be used in one of my projects.

  8. pengxwang says:

    you should really attribute the plugin to john resig. he wrote the original. ‘nje’ just added a bunch of extra code to it. seems redundant to me, unless you can provide a demo of those features, and not just the core feature already provided by resig’s code.

    • Rey Bango says:

      Not sure why I would. This is an independent plugin and while some code is based off of John’s work, it’s gone off on its own and added a number of features. In fact, John & I are working with the Microsoft team to improve this specific plugin and is being considered for official plugin status.

      As far as showing you a demo of the extra features, you should check out the plugin to see what’s available. Sounds like you haven’t really done that and there’s no sense in waiting for me. :)

      • Brandon says:

        Wrong. It was created by John Resig, and forked by Boris (who works at Microsoft). He may have made major contributions, but saying the plugin was “created by Microsoft” is nonsense.

        • Rey Bango says:

          Hi Brandon. You’re pretty snarky, especially for someone who wasn’t there when it was being built. On the other hand, I was actually there because I was a member of the jQuery Project team and an employee of Microsoft when it was in development. In fact, John, Boris & I had plenty of chats about this new version of the templating engine.

          jQuery tmpl and John’s Micro Templating experiment are incredibly different in both code bases and functionality. It’s quite possible that Boris may have looked at John’s original code but what John & Boris built are vastly different. Just look at John’s code and Boris’ code.

          Further, John mentioned the fact that we had originally considered using his Micro Templating engine but the new Microsoft version was much more robust. via Ajaxian:

          “John told me his original Micro-Templating library was considered at one point, but the new templating is more refined.”

          So yes, the jQuery templating plugin was created by Microsoft and leveraged a lot of the in-house knowledge that MS had in their own JS-based templating functionality.You’re grossly underestimating the work that went into this and the amount of MS in-house knowledge that was leveraged. And if you look at JSRender, the better version of jQuery tmpl, the differences are even more obvious.

          Lastly, please tone done the snarkiness and try a more friendly approach. It goes a lot farther with me.

          • Brandon says:

            You say “It’s quite possible that Boris may have *looked* at John’s original code” but Boris clearly states that he forked John’s code. If you were there you should know this.

            The question of how different they are is a red herring. The point is that it did not originate at or with Microsoft the way you claim. No matter how much Boris (or other Microsoft employees) changed it, it did not originate inside Microsoft. Boris is quite up-front about this, so why can’t you be? I’m in no way putting down his contributions, as I’m sure they are very considerable. But no matter how sizable his contributions were, your claim is false. Someone already pointed this out to you and you dismissed them. Now you say I’m snarky for pointing it out more bluntly.

          • Rey Bango says:

            So it sounds like we’re arguing semantics.

            I’m saying the Microsoft created the plugin, as in “built it”. I clarified in a subsequent reply to you that it was a fork of John’s original code but the end result is vastly different and it’s a totally different plugin. All you have to do is look at the code. If you’ve done that, you’ll see it. That to me constitutes a whole new creation and one that was built by Boris (and Microsoft). He had input from the jQuery team as to how to create the API to better fit within the jQuery style.

            What I’m reading from you is that your point of contention is that the idea didn’t originate from MS. Is that correct?

            And yes, you were being snarky. Certainly happy to have a conversation but completely uninterested in your bluntness.

        • Rey Bango says:

          And just to be clear, the original was a fork, just as Boris mentioned before but the end result is very far from what John’s original code was, especially in JSRender.

  9. I started putting this script to use and thought about a very nice addition. Wouldn’t it be nice if the data object that was passed through was added to the template’s parent element’s data cache? Accessible via $.data.

    Also, is the current build able to treat some data as HTML? So line1<br/>line2, will show as:

    line1
    line2

    rather than ‘line1<br/>line2′.

    Excellent work :)

  10. Dave Reed says:

    @John Strickler
    There’s a context that is accessible that contains everything you have access to within the template. You can retrieve a context from any element inside the instance of the template: $(selector).tmpl().data.

    For writing content you want to allow html in,
    {{html foo}}

  11. Boris Moore says:

    Thanks for the various comments above.

    To give a bit of context, this is a fork of John’s prototype, which we have been using to explore some scenarios. It is currently pretty much in flux, so we haven’t been drawing attention to it up to now, or providing API documentation. But quite a few of the recent changes are actually a result of input from John, following his review of where we were at a couple of weeks ago.

    As to the set of features, nothing is decided yet – we are aiming at splitting it into a set of more important features (currently jquery.tmpl.js) and some additional features in a separate plugin (jquery.tmplplus.js). But which parts go in which is under discussion with John, and things could move in either direction.

    There is quite a lot that was not at all in John’s original prototype, including composition through the {{tmpl}} tag (partials), being able to get to the template context (which provides access to the data item, the HTML nodes, the parent context – for nested templates, etc.), improved support for passing parameters to tags in markup, and so on. Take a look at the sample demos, including the movies demo, to get a sense of some of the features that are currently in there.

    On the documentation, we will add a Wiki to the github repo very soon, and also try to add more demos as we move along…

    Absolutely agree about being able to use external/remote templates, and that is on the roadmap, though some workarounds are already available.

    • Brad says:

      Just wanted to point out that John’s original prototype doesn’t actually require any changes in order to enable features like partials (nested templates) or counting iterators. I was able to plug those features in through John’s tmplcmd interface.

      The tmplcmd’s themselves are discreet one or two line decorators that aren’t tightly coupled with the core tmpl engine. I prefer that approach, since it keeps specific use cases out of the general templating engine.

      When I looked at the Microsoft approach, there were a number of added dependencies that just wouldn’t be useful 80% of the time. The additional API for event-binding, prerendering and postrendering seemed overly complex too, especially in a world with jQuery delegate().

  12. [...] the original post: Not Using jQuery JavaScript Templates? You’re Really Missing Out. – Rey Bango 9 July 2010 | Uncategorized | Trackback | del.icio.us | Stumble it! | View Count : 0 Next Post [...]

  13. I just finished a project where I used jQuery Template and I don’t regret that, you can check it out here http://goo.gl/3Bqj

  14. papichulo says:

    I don’t get. What’s the whole purpose of loading javascript libraries and rendering data into a template with javascript. What is wrong with the normal way of outputting data in Coldfusion, PHP, etc? It is just a template after all. If you need to do some manipulation afterwords without making a server call then use javascript, but for templating???? Help me understand.

    • Jan Hohner says:

      It reduces traffic because the template is cached in the js-file. If you use PHP, CF, etc templates, you have to transfer the template every time you use it.

  15. Not Using jQuery JavaScript Templates? You’re Really Missing Out. – Rey Bango…

    Thank you for submitting this cool story – Trackback from DotNetShoutout…

  16. JGarrido says:

    One thing that seems like a potential deal-breaker for some, unless I’m missing something, is the incompatibility with server-side expression language or templating syntax used by Java’s EL within JSP files and Grails’ GSP files. Does anyone know if there is the option of defining a different wrapper then the default ${} provided with this templating engine?

    It would obviously only cause issues with JS contained within a server-side parsed file, but that could definitely cause enough disincentive.

  17. Jan Hohner says:

    Like the template in a template feature, nice one! Using it as template in a template in a template :D

  18. Boris Moore says:

    @JGarrido
    For the case where you are using a server-side expression language which uses the ${foo} expression, you can just use the longer form, client-side: {{= foo}}.

    Client-side, ${foo} is just a shorthand for {{= foo}}, so the two forms are completely equivalent…

    • JGarrido says:

      Ah great to know, that would certainly resolve it. Maybe I’ll take a look at it after all, thanks for the tip.

  19. [...] Shared Not Using jQuery JavaScript Templates? You’re Really Missing Out. – Rey Bango. [...]

  20. [...] Not Using jQuery JavaScript Templates? You’re Really Missing Out – Rey Bango takes a look at the use of templating libraries for jQuery and JavaScript, showing how much easier they make reading your code and illustrating some of their capabilities. [...]

  21. [...] Not using jQuery JavaScript Templates? You're Really Missing Out (Rey Bango) [...]

  22. Harry says:

    Ray, according to this benchmark the jQuery Template plugin is outperformed by jQote
    http://github.com/aefxx/jQote2/blob/master/jqote.benchmark.htm
    I extended this benchmark, the result can be found here: http://www.harryklein.name/img/jquote_benchmark.png

  23. [...] Not Using jQuery JavaScript Templates? You’re Really Missing Out. – Rey Bango – [...]

  24. [...] In my last post, I presented an intro to how to create a template using the new jQuery Template plugin being developed by the Microsoft Ajax Core team. In this tutorial, I’ll show you how to nest templates to have great control over your layout. [...]

  25. Smithey says:

    I’ve never seen raw HTML inside a script tag. Frankly this bit of code scares the shit out of me.

    A script tag with a mime-type of ‘text/html’. Oh the horror! Is this a HTML5 thing. Does HTML5 allow this super-hacky way of writing code?

  26. [...] share, do not hesitate to share them here: Submit News.When Designers And Developers Work TogetherNot Using jQuery JavaScript Templates? You’re Really Missing OutWhich loads faster?Supersize that Background, Please!A Beginner’s Guide to Design [...]

  27. aefxx says:

    Hey Ray,

    I thought I’d plug my own little templating engine here as my benchmarks were quoted by Harry above.

    You guys might want to have a look at http://aefxx.com/jqote-plugins/jqote2. The first version was originally based on Resig’s brilliant code snippet that has/had some shortcommings (mainly parsing and caching), though.

    jQote2 then was rewritten from scratch, faster, more stable and now offers (almost) everything you’d ever want from a client-side templating solution:

    - Template precompilation to JavaScript lambdas (i.e. functions)
    - Caching mechansim to ease the compilation perfomance hit
    - Convenience methods to append/prepend and substitute template outcome within a container
    - Custom jQuery events that feature live/delegate binding
    - Exception handling that aids in debugging errorneous template code

    Give it a try. You won’t regret it.
    Nice day,
    aefxx

    • Rey Bango says:

      Hehe no worries. I’m glad you came over. Having different options is great. I even mentioned jQote in my presentation on Monday on jQuery Templating.

  28. [...] today Rey Bango posted an excellent article about jQuery Templates (Not Using jQuery JavaScript Templates? You’re Really Missing Out.) This was something I had meant to look at before but just never got around to it. If you [...]

  29. [...] far in my series on jQuery JavaScript Templating, I’ve showed how to create a basic jQuery JavaScript template and then nest templates for increased layout flexibility and maintainability. If you haven’t [...]

  30. Lenny Breau says:

    I’m confused with this specific example. If you have to enter the data, why not just enter it in the UL and cut down on the amount of code in the page? Granted, this example is small, but why assign data to a variable and then enter that actual data for the variable in the html?

    The point should be able to be given an xml file or a comma-delimited text file, or excel or whatever that has scads of information that one would want to utilize in the given format. Then, a small generic script is written to say “go to the file and grab column A and assign it the variable “name” then, put that value in the page here..”

    A template seems to just be a different approach to a plug-in just like an ipod cast is just a mp3

    • Rey Bango says:

      @lenny: Yes of course grabbing remote data would be the most likely use case. I’m providing a variable containing data so readers can work with it. If you look at the demo code I recently uploaded from my presentation you can see it uses an XHR call to return JSON data and render it in a template.

  31. Olivier says:

    Hi,

    This library is great but unfortunately seems not work with jQuery 1.3.2, I get an error (“pntNode is null” in processItemKey function). Is it necessary to move to jQuery 1.4 or do you have a workaround or advices please ? thans a lot.

  32. Chris says:

    Has there been any updates to include $context or $index as described in the proposal: http://wiki.github.com/nje/jquery/jquery-templates-proposal#context

  33. Jorge Pedret says:

    Hey Rey,

    I have a question:

    Is there a way to relate the original data used to render the template with the rendered elements?

    Suppose I have my data array that I use to render the template. Once it’s rendered, I update some of the generated markup, how can I update the original data array used to render?

    I’m creating a layout builder, which has internal elements that can be updated with a form that popups when you click each element. My plan is to store the data array into a database, that’s why I need to update it.

    Is this something doable? Is there another way to approach this problem?

    Thanks a bunch!

  34. [...] to jQuery Templates by Stephen Walther Introducing jQuery Templates 1: First Steps by Boris Moor Not Using jQuery JavaScript Templates? You’re Really Missing Out. by Rey [...]

  35. Ras Fred says:

    This is definitely great tech, but almost a year after this post the Templates are still beta – “This plugin is currently in beta form and may change significantly before version 1.0 is released.”

    Many project require a 1.0 version – are you seeing reasonable progress towards a 1.0 release? Thanks.

    • Rey Bango says:

      Hi Steve,

      The effort is now part of the jQuery UI project which is looking at how to integrate it into the project’s architecture: Roadmap

      I would say to check out JsRender which is being curated by the original developer of jq-tmpl and is an optimized version of it as well as JsViews which incorporates data linking into the templates.

      • Ras Fred says:

        Hi Rey – the Roadmap link definitely helps me in determining how/when to use templating & what to keep an eye on moving forward. Thanks for your help!

  36. Chad Brown says:

    Also worth checking out is json2html (www.json2html.com), a plug-in for jQuery, that uses JSON templates that do not require compiling.

  37. Oren says:

    How easy is it to alternate styles, for example between the list items? Because if using a straight JavaScript loop, this would be trivial, ugly, but trivial. If using templates, I’m a bit dependant on the options available, not to mentions that I need to learn yet another skill. Can you please give the alternating styles as an example for how easy it is.

    With kind regards,
    Oren

    • Rey Bango says:

      Not really sure how easy it is but it could be a simple matter of using CSS psuedo classes to search for alternating rows and apply styles.

  38. jake says:

    Thanks Rey for this post. I’m obviously getting to this a little late, but I think still relevant to what I’m wanting to accomplish in terms of an artist site I’m wanting to create. I found this post through your series of Nettuts articles regarding Ember.js. Thanks for both!

Learn JavaScript!

What to Read to Get Up to Speed in JavaScript.

The best books & blogs for learning JavaScript development. Broken down by experience levels!


My BIG LIST of JavaScript, CSS & HTML Development Tools, Libraries, Projects, and Books.

Constantly updated with the latest and greatest tools. Check it out!

Categories

Rey Bango is Stephen Fry proof thanks to caching by WP Super Cache