HTML〈template〉Tag - Keep Markup & Javascript Code Separate

In present ajax driven web applications quite a lot of HTML content is dynamically inserted inside the page with Javascript. Typically code looks something like :

// assuming the ajax call sends back an array of images
$.ajax({
    type: 'GET',
    url: 'ajax.php',
    dataType: 'JSON',
    success: function(response) {
        var html = '';
        for(var i=0; i<response.length; i++) {
            html += '<div class="post">';
                html += '<img src="' + response[i]['image_src'] + '" />';
            html += '</div>';
        }

        $("#container").html(html);
    }
});

Problem with this approach : When the application becomes large, it becomes more and more difficult to keep inserting HTML content in this fashion. It starts bringing stress.

Furthermore assuming if there are 2 people writing the application, one an expert in HTML & CSS, and the second one writes Javascript code — it will be difficult for them to work together. The person knowing only HTML & CSS will be puzzled as to what to do.

Solution : It would be best if HTML & Javascript were kept separated. Assuming the HTML markup is defined in its own section, and in Javascript the HTML is just "imported", things would become a lot more manageable. And this is what the HTML <template> tag does.

HTML <template> Tag

The <template> tag holds HTML skeleton codes that are not rendered in the page but are still read by the browser. These skeleton codes can be manipulated with JavaScript and added to the page when and as required.

As an example, see the code shown above, this time defined inside a <template> :

<template id="post-template">
    <div class="post">
        <img />
    </div>
</template>

Using the <template> in Javascript

The content inside the <template> tag is cloned, manipulated and attached to the DOM or any other element.

The content is cloned by calling the cloneNode method. This method clones the node on which it is called.

var element = document.querySelector("#post-template").content;

// clones the div.post container inside the template
var clonedNode = element.cloneNode(true);

Setting true as the parameter of cloneNode clones all children of the node, which is obviously required. The default is false which results in only the node being cloned without its childrem.

This cloned content can then be inserted into the page. You can also change attributes and content of the child nodes.

// change the content of the cloned node
clonedNode.querySelector("img").setAttribute('src', 'http://site.com/img.jpg');

// append cloned node to a container
document.querySelector("#container").append(clonedNode);

Complete Example

For the example shown in the starting of this tutorial, see how you can achive the same result using a <template> :

HTML Markup :

<div id="container"></div>

<template id="post-template">
    <div class="post">
        <img />
    </div>
</template>

Javascript :

$.ajax({
    type: 'GET',
    url: 'ajax.php',
    dataType: 'JSON',
    success: function(response) {
        var template;
        
        for(var i=0; i<response.length; i++) {
            template = document.querySelector("#post-template").content.cloneNode(true);
            template.querySelector("img").setAttribute('src', response[i]['image_src']);

            document.querySelector("#container").append(template);
        }
    }
});

Useful Resources

Using templates and slots

Loading Comments