I doubt anyone was happier than I was to see that support for composite template rendering was added to jQuery Templates during the interim between the first community proposal and its recent release. If you’re a regular reader, you might remember that I personally lobbied for that functionality back in May, based on how I’ve used jTemplates’ similar #include feature.

Since then, a common question I’ve received amounts to: “Great, but why?”

I think that’s natural, because template composition is one of those things that can seem obscure until you put it to work for the first time. From that point onward, you’ll begin to see the structure of your client-side templates in a different light. Simplifying your templates into smaller logical parts and then combining those parts to create the desired end result is a powerful approach. It’s terrific for making large templates more approachable and maintainable over the lifetime of an application.

In this post, I want to show you an example of a scenario that template composition is well suited to, a couple ways that jQuery Templates’ {{tmpl}} feature can be used to simplify that scenario, and a bonus advantage that the composition approach provides even after the template has been rendered.

An example scenario: The invoice

Imagine that you need to display an invoice for a company that resells taxable items and also sells services. Ideally, the invoice line items for those separate “types” should be displayed with different markup. To explore a simple example of that, let’s create a template to render the invoice for a fictional web development company.

Whether retrieved from a server-side endpoint or embedded in the page during initial rendering, the underlying data for that invoice might be structured something like this:

Following from that data structure, our goal for the invoice’s markup might look something like this:

Notice that the markup for service and item rows is structurally different, to better represent the underlying data. When that’s desirable, composing sub-templates is the way to go. As we’ll see next, the alternative is unappealing.

The old fashioned way

The key to our goal of rendering different markup for services and items is to render different template code depending on the line item’s type property.

Of course, it’s possible to achieve that without using template composition. The {{if}} template tag allows you to concoct just about any conditional rendering scheme that you can image. For example:

That works, but it’s a mess.

Even with only two types of items, the template is already fairly difficult to read and digest. Just imagine if there were a dozen item types instead of only two. Bundling all the templates together would quickly become a maintenance nightmare.

Wouldn’t it be nice if we could separate the row templates and define them individually? The {{tmpl}} template tag allows us to do just that.

Reorganizing the template for composition

First, we need to separate the template into a container and individual row templates for each line item type. The container will be rendered once for every invoice, and the row templates as dictated by the underlying data.

In this case, the container template will simply begin and end our <table>. In a real-world template, this is where you might also include a <thead> with column headings.

The row templates are straightforward, extracted from the combined template we looked at in the last section:

Note that the templates have IDs that correspond to the type they’re designed to render. That will come in handy a bit later.

Template composition with jQuery Templates

Now, it’s finally time to add that composition magic to the container template. jQuery Templates has a special template tag which provides for rendering and composing nested templates: {{tmpl}}.

The {{tmpl}} tag has several usages (documentation), but the one I want to focus on is the one that accepts a selector as its template parameter. When a selector is specified, jQuery Templates locates the indicated template, renders it, and then replaces the {{tmpl}} token with that rendered markup.

The {{tmpl}} command also accepts a parameter specifying what data the sub-template should be rendered with. Including the template selector, the command will look like this: {{tmpl(dataItem) "#TemplateID"}}.

Putting that all together, this container template will use each item’s type to render the item with the appropriate row template:

If you aren’t familiar with {{each}} and its $value pseudo variable, all you need to know is that it contains the current iteration’s data item. It’s the same value that you would normally capture as the second parameter to an $.each() callback. In fact, {{each}} can also be used in that fashion instead:

I prefer using the pseudo variable since it’s more concise, but both are equivalent.

For now, we’re still stuck with the {{if}} to determine which row template to render, but getting the row templates out of that conditional block has cleaned things up quite a bit. Don’t worry if the conditional strikes you as a distasteful remnant of the original approach. We’ll fix that soon.

Rendering the composite template

Having defined the container template and its sub-templates, using jQuery Templates to render the entire group is just as easy as rendering a single template. Assuming the same invoice variable as seen before:

As far as we know at the time we render the container, nothing has changed (and that’s part of the point), yet the refactored template is going to be quite a bit easier to understand and maintain.

Unconditional rendering love

Now that the templates are separated, things are a lot cleaner than before. However, that remnant {{if}} block is still a bit irritating. If you end up with more than just a couple item types, the conditional will require ongoing maintenance and cruft up the template badly.

Instead of that explicit testing and branching to pick the right template, we can clean things up by automatically searching for a row template that matches our naming convention of typeRowTemplate. To do that, we just need to build a JavaScript function that takes a type parameter and returns the appropriate selector string:

Updating the container template to use our new function completely eliminates that {{if}} block:

Now, adapting to new item types is as simple as creating an appropriately named template. Convention over configuration, as they say.

Bonus: Rendering additional line items

Cleaning up the template is a good enough reason alone to use template composition, but the benefits extend beyond the initial rendering process. A nice side-effect of the compositional approach is that it’s easy to render additional rows even after the template has been rendered.

It’s easy to imagine that we might need to let users add new items to our invoice after it has been displayed. Assuming the invoice is already rendered, adding a matching row to it is as easy as this:

That’s cleaner, easier, and faster than the common alternatives of cloning an existing row, building the HTML manually, or completely re-rendering the entire table with updated data.

Perhaps more importantly, it centralizes your presentation code. When changes only need to be made once, in a single location, you are guaranteed to see less bugs over time.


I’ve been using this compositional approach with jTemplates for a couple years now, and I cannot overstate how helpful it is when you’re working on real-world apps with large, complex client-side templates. I do hope you’ll give it a try in your own projects, because I know you won’t be disappointed.

Kudos to everyone who worked on jQuery Templates and helped {{tmpl}} see its way into the first release. I think it’s an excellent implementation of the feature – certainly easier to use and understand than jTemplates’ #include.

An important piece of the puzzle that’s still missing at this point is a technique for storing these composite template groups in an external file and loading them asynchronously, as with single templates in my last post. Unfortunately, the simplistic approach in my previous post doesn’t work with composite templates. However it’s still very easily doable. I’ll cover that next, so stay tuned.

What do you think? Are you using template composition already? If not, have I managed to entice you to give it a try?