Search code examples
htmlmustachehtml-templates

Store HTML templates in HTML


I need to store HTML templates to use them for Mustache rendering.

<!-- Templates. -->
<span style="display:none">

<span id="tplCard">
    {{#.}}
    <div class="card">
        <div class="caption">
            <p>{{caption}}</p>
            <button title="Edit" class="toolbar edit"></button>
        </div>
    </div>
    {{/.}}
</span>

<span id="tplRow">
    {{#.}}
    <tr>
        <td>{{id}}</td>
        <td>{{caption}}</td>
        <td>{{text}}</td>
        <td>{{image}}</td>
        <td>
            <button>Edit</button>
        </td>
    </tr>
    {{/.}}
</span>

</span>
<!-- End of templates. -->

Here is the using:

function FillWithData(container, template, data)
{
    var tpl = $('#' + template).html();
    var html = Mustache.render(tpl, data);
    $('#' + container).append(html);
}

The first template works, but the second one doesn't. Well, the problem is a <TR> is not a valid child for a <SPAN>, so the browser gets rid of them. How to store a random template?


Solution

  • you can store the template data in a script tag. this will prevent the browser from parsing it as html. But you need to keep in mind that your template cannot contain script tags itself (Including <script> tag in <script type="text/template"> tag). (this works with <!doctype html> but honestly i can't say for sure if it would work that way cross browser for other doctypes)

    you would not need to change much in your setup:

    HTML

    <script type="text/x-template" id="tplCard">
        {{#.}}
        <div class="card">
            <div class="caption">
                <p>{{caption}}</p>
                <button title="Edit" class="toolbar edit"></button>
            </div>
        </div>
        {{/.}}
    </script>
    
    <script type="text/x-template" id="tplRow">
        {{#.}}
        <tr>
            <td>{{id}}</td>
            <td>{{caption}}</td>
            <td>{{text}}</td>
            <td>{{image}}</td>
            <td>
                <button>Edit</button>
            </td>
        </tr>
        {{/.}}
    </script>
    

    type="text/x-template" is used so that the browser would not try to execute it as a script.

    JS

    function FillWithData(container, template, data)
    {
        var tpl = $('#' + template).text()||$('#' + template).html();
        var html = Mustache.render(tpl, data);
        $('#' + container).append(html);
    }
    

    the $('#' + template).text()||$('#' + template).html() is required because in some browser versions you need to use .text() and in the other you need to use .html() to get the content of the script tag.