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?
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With