javascriptunderscore.jsgruntjsjstgrunt-contrib-jst

grunt contrib-jst to render underscore templates is not formatting properly


I'm trying to use grunt-contrib-jst to compile my underscore templates, but it seems to not be rendering / preserving the variables properly. Here's what a template looks like normally:

<script id="header-template" type="text/template">
    <h4><%= subhead %></h4>
    <h1><span class="head-text"><%= head %></span>
      <span class="subtext"><%= subtext %></span>
    </h1>
    <p></p>
  </script>

and here's what gets rendered via grunt:

this["JST"] = this["JST"] || {};

this["JST"]["templates/header.html"] = function(obj) {
obj || (obj = {});
var __t, __p = '', __e = _.escape;
with (obj) {
__p += '<h4>' +
((__t = ( subhead )) == null ? '' : __t) +
'</h4>\n<h1><span class="head-text">' +
((__t = ( head )) == null ? '' : __t) +
'</span>\n  <span class="subtext">' +
((__t = ( subtext )) == null ? '' : __t) +
'</span>\n</h1>\n<p></p>';

}
return __p
};

Here's how I set up my grunt task:

jst: {
      compile: {
        files: {
          "scripts/templates/all.js": ["templates/*.html"]
        }
      }
    }

and when I attempt to utilize the template:

var app = app || {};

app.HeaderView = Backbone.View.extend({
    el: '#header-container',
    //template: _.template( $( '#header-template' ).html() ),
    template: JST['templates/header.html'](), //http://stackoverflow.com/questions/8366733/external-template-in-underscore

    initialize: function( templateContent ) {
        this.render(templateContent);
    },
    render: function(templateContent) {
        this.$el.html(this.template(templateContent));
        return this;
    }
});

I get this error:

Uncaught ReferenceError: subhead is not defined

Any idea what's wrong and how to maintain the formatting of my original templates?


Solution

  • You say that you are

    [...] trying to use grunt-contrib-jst to compile my underscore templates

    That's exactly what's happening. If you look at the _.template docs, you'll see this:

    The source property is available on the compiled template function for easy precompilation.

    If you do this with that <script>:

    var t = _.template($('#header-template').html());
    console.log(t.source);
    

    you'll see that ugly function in the console.

    Demo: http://jsfiddle.net/ambiguous/WjNGC/

    So your JST task is simply compiling your templates using _.template and then dump the compiled template function's source attribute to a file; then, when the browser loads that JavaScript file, you get the compiled template back.

    The result is that you can say this:

    var html = JST['templates/header.html'](data);
    

    and get the filled-in template in html without having to compile the template in the browser.