Thursday, April 25, 2013

Introducing HTML’s new template element

Introducing HTML’s new template element
You may have heard of Web Components, a suite of emerging standards that make it possible to build secure reusable widgets using web platform technologies. One of the first specs to make its way into implementation is HTML Templates, embodied by the template element, which as I write this is implemented in Chrome Canary and Firefox Nightly.

If you've used Mustache, Handlebars or any similar front-end templating library you'll be quite familiar with how the template element works: you just include it in your document (it's apparently legal inside head or body), perhaps with a unique id for easy reference and add some markup inside it; for example:

<template id="foo">
  <h2>Hello, world!</h2>
  <hr>
</template>

The template element will be parsed by the browser but not rendered in the page; the markup inside is considered completely inert, meaning no style rules will be applied and no assets loaded. In order to use the template markup you'll need to activate it by placing it into the DOM using JavaScript. As an illustration let's presume I have the above markup in my document, along with some content which will be rendered:

<div id="bar">
  <h1>The template element</h1>
</div>

What I want to do is make a copy of the markup inside the template element by using the cloneNode() method on the content property, then insert it into the DOM; I'll do this using the appendChild() method. To achieve this, my script looks like so:

var foo = document.getElementById('foo'),
    bar = document.getElementById('bar'),
    cloned = foo.content.cloneNode(true);
    bar.appendChild(cloned);

Now the h2 and hr elements will be appended to div#bar, after the h1 element; note that the markup becomes active at this point, so any relevant assets will be loaded. The resulting markup will appear like so:

<div id="bar">
    <h1>The template element</h1>
    <h2>Hello, world!</h2>
    <hr>
</div>

As mentioned, this is already implemented in Chrome Canary (you'll need to enable the experimental WebKit features flag in chrome://flags/) and Firefox Nightly, although there's no news yet on when this will be in a release version.

This is a really simple example, but hopefully you can see how rich with potential this is; you can dynamically update the code each time you clone it, making it totally reusable. The template element is just a small part of Web Components, which I'll be aiming to cover in more detail over the coming months.

NB: After writing this post I found the article HTML's New Template Tag on HTML5 Rocks!, which covers the subject in a little more depth. It's written by Eric Bidelman, who's pretty much the authority on Web Components.

Update: I should point out that when the spec is fully implemented, templates will be shareable across multiple pages by linking to them in the document head:

<link rel="import" href="templates.html">

View Demo