Search code examples
javascripthtmlw3cpolyfillshtml5-template

HTML Templates JavaScript polyfills


I'm looking for the most standards-compliant / future-proof method for front-end HTML templating.

There exists a relatively new W3C draft specification for HTML Templates, e.g.:

<template id="mytemplate">
    <img src="" alt="great image">
    <div class="comment"></div>
</template>

Does anyone know if any good JavaScript polyfills already exist to make <template> element usable in a cross-browser way? Preferably complying with this standard.


Difficulties

According the the HTML5Rocks guide these templates have the following properties:

  • "Its content is effectively inert until activated"
  • "Script doesn't run, images don't load, audio doesn't play,"
  • "Content is considered not to be in the document"
  • "Templates can be placed anywhere inside of <head>, <body>, or <frameset>"

I think it is impossible to implement all four of these properties purely with a JavaScript polyfill, so any solution would only be partial.


Solution

  • There is a jsfiddle that demonstrates such a polyfill.

    <script>
        // Shim so we can style in IE6/7/8
        document.createElement('template');
    </script>
    
    <template id="example">
        <h1>
            This is template content.
        </h1>
        <p>
            It's really great.
        </p>
    </template>
    
    
    <div id="target">
        <p>
            This is regular old content.
        </p>
    </div>
    
    /* POLYFILL */
    (function templatePolyfill(d) {
        if('content' in d.createElement('template')) {
            return false;
        }
    
        var qPlates = d.getElementsByTagName('template'),
            plateLen = qPlates.length,
            elPlate,
            qContent,
            contentLen,
            docContent;
    
        for(var x=0; x<plateLen; ++x) {
            elPlate = qPlates[x];
            qContent = elPlate.childNodes;
            contentLen = qContent.length;
            docContent = d.createDocumentFragment();
    
            while(qContent[0]) {
                docContent.appendChild(qContent[0]);
            }
    
            elPlate.content = docContent;
        }
    })(document);
    
    /* EXAMPLE */
    var elExample = document.getElementById('example'),
        elTarget = document.getElementById('target');
    
    elTarget.appendChild(elExample.content.cloneNode(true));
    

    As for libraries, and I don't know that they support it yet, but try something like Modernizr and Initializr