Introducing the new HTML5 template Tag

Modern web applications use DOM manipulation to dynamically change areas of the page or insert values. A typical example is a table of figures; the initial page could return HTML column headers then initialize an Ajax request which returns several data records. The data is then appended to the table — but how? The developer has two choices:

  1. JavaScript is used to build HTML row strings or DOM fragments which are appended to the table. That seems easy until you need to make a change and must hunt around your JavaScript for the associated HTML code. To make life simpler, developers often return whole HTML string fragments from the Ajax call, but that makes the payload more verbose and opens the potential for Cross-Site Scripting attacks.
  2. Alternatively, you create an empty first row in the HTML page which is used as a template for all other rows. That should be easier to maintain, but you’ll need to remove it from the DOM or style it with display:none to ensure it doesn’t appear.

Neither solution is particularly elegant.

Fortunately, the W3C has introduced a new template tag which provides a mechanism to define HTML markup fragments as prototypes. (Perhaps it will also appease those upset by the demise of the hgroup element!)

In essence, a template can be used to insert fragments of HTML code into your page, e.g.

<template id="mytablerow">
<tr>
<td class="record"></td>
<td></td>
<td></td>
</tr>
</template>

The template code can be defined almost anywhere — the head, body or even a frameset. However:

  1. templates will not display
  2. templates are not considered to be part of the document, i.e. using document.getElementById(“mytablerow”) will not return child nodes
  3. templates are inactive until used, i.e. enclosed images will not download, media will not play, scripts will not run, etc.

Using templates

To use a template, it must be cloned and inserted into the DOM. For example, assuming the following HTML:

<table id="mytable">
<thead>
<tr>
<td>ID</td>
<td>name</td>
<td>twitter</td>
</tr>
</thead>
<tbody>

<!-- rows to be appended here -->

</tbody>
</table>

<!-- row template -->
<template id="mytablerow">
<tr>
<td class="record"></td>
<td></td>
<td></td>
</tr>
</template>

We can clone a new row in JavaScript:

// fetch tbody and row template
var	t = document.querySelector("#mytable tbody"),
	row = document.getElementById("mytablerow");

// modify row data
var td = row.getElementsByTagName("td");
td[0].textContent = "1";
td[1].textContent = "SitePoint";
td[2].textContent = "sitepointdotcom";

// clone row and insert into table
t.appendChild(row.content.cloneNode(true));

The important question: can we use template tags?

Probably not just yet. It’s supported in the latest version of Chrome and Firefox nightlies. Opera will support the tag when it switches to Blink. No word from the IE and Safari teams yet, but a template shim has been demonstrated on JSfiddle should you wish to support all browsers.

Personally, I think the template tag is a great idea. It’s simple and standardizes templating techniques for HTML5 developers.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Cobey

    I’m slightly confused. In the first example you stated that document.getElementByID would not return any results, yet in the second example you use that very construct to clone the template. Am I missing something?

    Thanks!

    • http://www.optimalworks.net/ Craig Buckler

      If my understanding is correct based on the samples I’ve seen, the template is not part of the main document, i.e. document.getElementsByTagname("td") wouldn’t return any of the elements within the template.

      What you’re effectively doing is instantiating an in-memory document fragment, but that fragment is generated by the template HTML rather than using var f = document.createDocumentFragment() and building it yourself. Once you have that object, you can access its nodes, manipulate them and change content. However, it won’t appear on the page until it’s cloned and appended to a visible part of the page.

      Of course, this could all change when it’s implemented in browsers.

      • QED

        I guess that would be the difference when compared to just dumping your templates into a div with class=”template” and display:none. The downside to using the div is that it would be accessible to dom queries within the rest of the document. Of course, you could load them into javascript objects and remove them from the dom on page load. Just sayin…

  • http://richardrazo.com Richa

    Yeah, I agree with Cobey. Maybe it’s my lack of js know-how but nevertheless can someone clarify the difference between not being part of the DOM yet being able to target it?

  • adrea cruz

    thank you for sharing a bit confused

  • kroleek

    I don’t understand what is benefit of this :(
    You still need to use getElement.. function to deal with objects inside template.
    It would be much more awesome if template have some “eval” behavior like in common JS templating systems (just give an data object and render template).

    • http://www.optimalworks.net/ Craig Buckler

      The benefit is that you’re able to create a real DOM fragment in the HTML page without lots of JavaScript code or using innerHTML strings. The DOM is a rudimentary templating system but there’s no reason why you couldn’t build further functionality on top.

  • http://raym31.home.comcast.net Ray

    How would the tag be affected by begin commented out, in an attempt to provide graceful deg?
    eg.:<!– ..–>

    • http://www.optimalworks.net/ Craig Buckler

      I guess that wouldn’t work. The best way to make it degrade gracefully would probably be to place it in the HTML head.

  • Doug

    It’s probably just me, but this doesn’t seem to be that… necessary? It sounds like an edge-case or too specific for the standard. I guess in my mind, I wouldn’t consider Javascript manipulation of the DOM when deciding what tags should be in the standard. I suppose that JS and HTML are forever stuck together, but is there any use for a template tag outside of JS? Over the last few years, I’ve be reading “semantics, semantics, semantics”. The template tag doesn’t seem “semantic”.

    • http://www.optimalworks.net/ Craig Buckler

      Thanks Doug. It’s an interesting point. Currently, the template tag is primarily of use to JavaScript development although there’s no reason why it couldn’t be used elsewhere, e.g. automatically repeating elements defined in HTML or CSS.

      As for semantics, I think it’s preferable to define an HTML template in HTML rather than JavaScript. That said, it’s not really part of the page and will probably confuse search engines until they recognize the container.

      Overall, there have been many times I would have found templates useful. For that reason alone, I think they’re a generally a good idea.

  • http://www.domtemplate.com/ Mick Boo

    We’v been using a system similar to this for years in PHP. If PHP5 starts supporting DOM templating this could be a real bonus…
    feel free to check it out:

  • Michelle Diamond

    I am a designer and find I can get quite lost when I open a site I have not worked on for some time or when code transforms from what I created to what the js coder adds, etc.. this will be a great help. I am really excited about it. I think it will keep the design intact.

  • http://www.dzpage.com Mourad

    I think Javascript MVVM frameworks will use this new tag.

  • http://www.shdon.com/ Steven Don

    I’ve abused the xmp tag for this, as HTML inside that is not parsed either. A simple xmp{display:none;} is sufficient as it doesn’t get used normally anywhere. Works like a charm, except the xmp tag is now deprecated :(

  • BT

    You may or may not know that you can use something like Handlebars or Underscore to write out templates in your HTML. It’s not as “pure” as having an actual tag, sure, but until that option is available, I would much rather see people doing this than store mass strings of HTML in their JavaScript.

  • mohsen_shafiee

    thanks,
    how can i attach addEventListener to element into template tag?