On Handlebars and Template Tags

Published Jun 17, 2014 Updated Jul 5, 2022 3 min read

Handlebars is awesome. I can separate my template logic from my application logic? Yes, please. When I try to use Handlebars in my local editor, though, it vomits all over those ugly <script> tags. Fortunately there’s an awesome, future-friendly, spec-compliant solution — the <template> tag.

<template> tags are super cool in a lot of ways. From the HTML5 Rocks article, here are the pillars of <template> tags:

  1. Its content is effectively inert until activated. Essentially, your markup is hidden DOM and does not render.
  2. Any content within a template won’t have side effects. Script doesn’t run, images don’t load, audio doesn’t play… until the template is used.
  3. Content is considered not to be in the document. Using document.getElementById() or querySelector() in the main page won’t return child nodes of a template.
  4. Templates can be placed anywhere inside of <head>, <body>, or <frameset> and can contain any type of content which is allowed in those elements. Note that “anywhere” means that <template> can safely be used in places that the HTML parser disallows…all but content model children. It can also be placed as a child of <table> or <select>:
<table>
  <tr>
    <template id=”cells-to-repeat”>
       <td></td>
    </template>
  </tr>
</table>

Why isn’t this being used elsewhere?

That’s a great question. I can only speculate but I’d reckon it has something to do with the recency / lack of support. <template> is supported in most browsers, though Can I Use tells us that we’re lacking support in Internet Explorer (big surprise), Safari 7, and Blackberry. Luckily, we can add this shim if we need to make it work everywhere. You can read more about the <template> tag and how to use it in this tutorial on HTML5 Rocks.

Here’s the coolest thing, though — current Handlebars users will actually have to write less code. Check it:

<!-- Handlebars recommended template block syntax -->
<script type=”text/x-handlebars-template” id=”article-template”>
  <article>
    <h1>{{title}}</h1>
    {{content}}
  </article>
</script>

…just swap the <script> tags for <template> tags:

<!-- The exact same thing using template tags -->
<template id=”articleTemplate”>
  <article>
    <h1>{{title}}</h1>
    {{content}}
  </article>
</template>

And blammo, you’re using awesome new HTML5 tech. Your editor and I will love you for it. 😉

The catch

As joao points out in the Codepen comments, not everything is hunky dory. Take a look at this code:

<template id=”tableTemplate”>
  <table>
    {{#each}}
      <tr>
        <td>{{content}}</td>
      </tr>
    {{/each}}
  </table>
</template>

Looks legit, right? Unfortunately it breaks in the browser. The parser still requires the code inside the <template> tag to be valid HTML which means you can’t have any content in a table unless it’s also inside a cell (<td>). You can, however, create your table cells / rows in a template tag and use them in a table:

<table></table>

<template id=”tableTemplate”>
  {{#each}}
    <tr>
      <td>{{content}}</td>
    </tr>
  {{/each}}
</template>

It’s not ideal and I would definitely prefer a better DOM API for it. Still, this stuff is super cool and I’ll be using it all over the place. If you take advantage of it, let me know! I’ll leave you with my implementation of <template> tags and Handlebars: