Search code examples
jqueryunderscore.jsunderscore.js-templating

From an underscore.js template to a DOM element


Right now I'm using the following line of code to retrieve an Underscore template and create a DOM element from the template, using jQuery.

var element = $(_.template($('#template').html())());

It works, but I think this looks a bit messy/confusing, so I was wondering if there's a better way to do this?


Solution

  • Updated for Underscore 1.7+: There's really not much better you can do in newer versions of Underscore since _.template always returns a function:

    template _.template(templateString, [settings])
    Compiles JavaScript templates into functions that can be evaluated for rendering.

    You used to be able to say _.template(tmpl, data) (see below) to get a filled-in template but no longer.

    You can however hide some of the parentheses inside a function with things like:

    var tmpl_to_html = function(id) {
        var $el = $('#' + id);
        var fn  = _.template($el.html());
        return fn();
    };
    var $e = $(tmpl_to_html('template'));
    

    or:

    var tmpl_to_html = function(id, data) {
        var $el = $('#' + id);
        var fn  = _.template($el.html());
        return fn(data);
    };
    var $e = $(tmpl_to_html('template'));
    var $x = $(tmpl_to_html('other', { a: 'b' }));
    

    For old versions of Underscore: You can get the filled in template from _.template by supplying the data parameter:

    template _.template(templateString, [data], [settings])
    [...]
    If you're writing a one-off, you can pass the data object as the second parameter to template in order to render immediately instead of returning a template function.

    Anything truthy will probably due for data but an empty object is probably your best bet:

    var $e = $(_.template($('#template').html(), { }));
    

    That's still a bit noisy but you can always wrap the _.template call in another function:

    var tmpl_to_html = function(id) {
        var $el = $('#' + id);
        return _.template($el.html(), { });
    };
    var $e = $(tmpl_to_html('template'));
    

    How you bust it into functions depends on your preference what parts you'd be using elsewhere.