Reputation: 648
I need to bundle client side templates for other people to use as part of a library of Backbone components. I can not use RequireJS or any other AMD solution.
The idea I've had is to combine all the HTML templates into a isngle JS file that defines variables to contain the templates. Then someone would just have to do:
<script type="text/javascript" src="/js/templates.js"></script>
templates.js could look something like
var ns = ns || {};
ns.templates = {};
ns.templates['my-special-list'] = "<% _.each(stuff, function(model) { %><li><% print(model.get('title')); %></li><% }); %>";
then my views could do things like:
var V = Backbone.View.extend({
initialize: function() {
if (_.isUndefined(this.template)) {
this.template = _.template(ns.templates['my-special-list']);
} else {
this.template = _.template(this.template);
}
}
render: function() {
this.$el.html(this.template.render(this.options));
}
}
This idea seems to work. Still allows people to pass in their own templates effortlessly while still letting me combine all our templates into a single HTML file at build time.
That said though, I sense complications combining all of this. For starters, every new line would need to be converted to \n, escaping characters, etc.
I can not think of another way to do it to be honest. I tried googling around and didn't see much that helps out. RequireJS just offers a nice way to load text but this doesn't help much for me.
Are there better ways to accomplish what I want or is my approach as good as it gets?
Upvotes: 3
Views: 224
Reputation: 1644
Are you familiar with Grunt? In one my projects I'm using the JST task to compile my individual templates into one file at build time. I store them each as individual HTML files and then have this in the Gruntfile.js:
jst: {
compile: {
options: {
namespace: 'app.templates',
processName: function(filename) {
// simplify the template names
filename = filename.replace('app/templates/', '');
return filename.replace('.html', '');
}
},
files: {
"<%= yeoman.app %>/scripts/templates.js": ["<%= yeoman.app %>/templates/{,*/}*.html", "<%= yeoman.app %>/templates/**/{,*/}*.html"]
}
}
}
My header template (app/templates/inc/header.html), for example, looks like this:
<h1 class='topbar-header'><%= title %></h1> <h2 class="subtitle"><%= subtitle %></h2>
Which is compiled by JST and made available via app.templates['inc/header']
which is a actually a function you call (not a string) with the object containing the parameters. In the case of my header template, I would have to pass in an object with title
and subtitle
properties.
var template = app.templates['inc/header'];
var code = template({title: 'Hello', subtitle: 'World'});
this.$el.html(code);
Upvotes: 1