Poni
Poni

Reputation: 11317

underscore.js template from an HTML element

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html>
<head>
<style type="text/css">
#template {
    display: none;
}
</style>
<script
    src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script
    src="http://documentcloud.github.com/underscore/underscore-min.js"></script>
</head>
<body>

    <div id="template">
        <div id="event">
            <button><%= title %></button>
        </div>
    </div>

    <button id="cmd_create_event" name="cmd_create_event" type="button">Create
        a new `EventModel`</button>

    <div id="div_event_list"></div>

    <script type="text/javascript">
        $(document).ready(function() {
            $("#cmd_create_event").click(function() {
                var template = $("div#template div#event").children().html();
                var compiled = _.template(template);
                $("#div_event_list").html(compiled({
                    title : "New Event Title"
                }));
            });
        });
    </script>

</body>
</html>

The above would work perfectly if the html() call wouldn't return this: &lt;%= title %&gt;

I want it to return exactly <button><%= title %></button>, as I wrote it in the HTML, so I can use it for templating with underscore.

How?

Alternatively, is there any better way? Without extra dependency (jquery/underscore only). Without (too much) extra code.

Upvotes: 2

Views: 2390

Answers (1)

Pointy
Pointy

Reputation: 413709

Instead of storing your template source in a <div>, put it in an unevaluated <script> block:

<script type='text/template' id='template'>
  <button><%= title %></button>
</script>

When you fetch the contents of that with .html(), you'll get the contents back exactly as they look. That "type" value is made-up (by me); you can use anything except a real JavaScript type, and the browser will just ignore it completely. It will however include it in the DOM and allow you to fetch its contents. Since the contents are not expected to be HTML, it won't care about the HTML metacharacters.

The conversion of your template markers to &lt; and '>' is being done by the browser because that's really what you've fed it: unescaped HTML metacharacters are really not allowed, but the browser recognizes that that's what the <% and %> are so it interprets them that way.

Upvotes: 4

Related Questions