jquery and HTML5's template tag

1.8k views Asked by At

I want to use underscorejs' templating function. It seems like HTML5's <template> tag would be an AMAZING fit for this, but there's a snag... The underscorejs interpolation tags (<% and %> get html-escaped, so HTML inside a template tag looks like so:

$('template.new-email').html()

=>

"
  <div class="email">
    <div class="timestamp">
      &lt;%= received %&gt;
    </div>
    <div class="from">
      &lt;%= from %&gt;
    </div>
    <div class="title">
      &lt;%= title %&gt;
    </div>
    <div class="message">
      &lt;%= message %&gt;
    </div>
  </div>
"

Well, that sucks.

Now, as it turns out, if I use a script tag with a fictitious type, like "x-underscore-templates", then it looks hunky-dory:

$('.new-email').html()

=>

"
  <div class="email">
    <div class="timestamp">
      <%= received %>
    </div>
    <div class="from">
      <%= from %>
    </div>
    <div class="title">
      <%= title %>
    </div>
    <div class="message">
      <%= message %>
    </div>
  </div>
"

So my question is -- can I use the template tag? How do I get just the characters I need, in a string, so I can pass them to underscore's templating system?

Note - since the server I'm using right now is a hapijs / node server that uses handlebars as a server-side templating system, I can't just use {{ and }}.

1

There are 1 answers

0
lossleader On BEST ANSWER

I also like the idea of using a template tag and I have tried to make underscore templates work in the html5 template element in various ways. Unfortunately, the template element specifically means a html template and the content will be transformed into a document fragment which is not appropriate for many valid underscore templates even if they will later render to valid html.

Consequently, the only usage I can suggest is that you could keep your script elements organized within a template element like so:

<template class="underscore-templates">
 <script id="new-email">
   <div class="email">
     <div class="timestamp">
       <%= received %>
     </div>
     <div class="from">
       <%= from %>
     </div>
     <div class="title">
       <%= title %>
     </div>
     <div class="message">
        <%= message %>
     </div>
   </div>
 </script>
 <script id="other">
 </script>
</template>

And then they are segregated to safely do things like:

var templates = $('.underscore-templates').prop('content');
_.template($(templates).children('#new-email').html(), {...});

with the template element serving as a scope to prevent the normal issues of id collision and executing these templates as scripts.

(Still, this would be limited to modern browsers without a pretty in depth investigation of how (or maybe if) you can retrieve the template elements content in older browsers and render it into a searchable fragment.)