I have a backbone model like this
var PeopleModel = Backbone.Model.extend({
defaults: {
\"people\": [
{ \"username\": \"alan\", \
Or to avoid using global scope you can mix in global template helpers like so:
(function() {
var originalUnderscoreTemplateFunction = _.template;
var templateHelpers = {};
_.mixin({
addTemplateHelpers : function( newHelpers ) {
_.extend( templateHelpers, newHelpers );
},
template : function(text, data, settings) {
// replace the built in _.template function with one that supports the addTemplateHelpers
// function above. Basically the combo of the addTemplateHelpers function and this new
// template function allows us to mix in global "helpers" to the data objects passed
// to all our templates when they render. This replacement template function just wraps
// the original _.template function, so it sould be pretty break-resistent moving forward.
if( data )
{
// if data is supplied, the original _.template function just returns the raw value of the
// render function (the final rentered html/text). So in this case we just extend
// the data param with our templateHelpers and return raw value as well.
_.defaults( data, templateHelpers ); // extend data with our helper functions
return originalUnderscoreTemplateFunction.apply( this, arguments ); // pass the buck to the original _.template function
}
var template = originalUnderscoreTemplateFunction.apply( this, arguments );
var wrappedTemplate = function( data ) {
_.defaults( data, templateHelpers );
return template.apply( this, arguments );
};
return wrappedTemplate;
}
}
}
Then call
_.addTemplateHelpers( {
partial : function() {
return _.template(
$('#' + which + '-partial').html(),
data
);
}
} );
Here is a link to the underscore mixin on github.
No, there is no native partial support in Underscore's templates. But, you can put pretty much any JavaScript you want inside <% ... %>
; in particular, you can call your own functions so you can add something partial-ish without much difficulty. You could have a template like this:
<script id="people-template" type="text/x-handlebars-template">
<% _(people).each(function(person) { %>
<%= partial('person', person) %>
<% }) %>
</script>
and then add a partial
function to window
:
window.partial = function(which, data) {
var tmpl = $('#' + which + '-partial').html();
return _.template(tmpl)(data);
};
Demo: http://jsfiddle.net/ambiguous/HDuj5/9/
That's not quite as slick and pretty as {{> ... }}
in Handlebars but Underscore's templates are a very thin wrapper around JavaScript itself and that limits you somewhat. You can use namespaces to avoid putting things directly in window
or you could use the {variable: ...} option to _.template and a wrapper to set up your standard helpers.
I think this is similar to Dave's answer, but perhaps requiring less code:
function partialTemplate(origTemplate, partialValues){
return function(values){
return origTemplate(_.defaults(values, partialValues));
};
}
Example usage:
var t = _.template('<%= val1 %>,<%= val2 %>'); // original template requiring 2 values
var pt = partialTemplate(t, {val1:1}); // partial template with 1 value pre-populated
pt({val2:2}); // returns '1,2'
pt({val2:3}); // returns '1,3'