1

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?

mheavers
  • 29,530
  • 58
  • 194
  • 315

1 Answers1

1

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.

mu is too short
  • 426,620
  • 70
  • 833
  • 800
  • sorry - see revised edits - I'm getting an error when I do this. And the variable 'data' does not seem to be accessible. – mheavers Nov 01 '13 at 22:35
  • 1
    `template: JST['templates/header.html']()` calls the template function, you want `template: JST['templates/header.html']` (no function calling parentheses). Then `this.$el.html(this.template(templateContent));` should work just fine. The `data` in my answer was just for illustrative purposes, you're using `templateContent` – mu is too short Nov 01 '13 at 22:47