My goal is to put all my Handlebars templates in a single folder, as so:
templates/products.hbs
templates/comments.hbs
I found this snippet in
You can read template from External file no need to put html with script tag
$.get('templates/products.hbs', function (data) {
var template=Handlebars.compile(data);
$(target).html(template(jsonData));
}, 'html')
The code is wrapped in an IIFE (Immediately Invoked Function Expression), which means the function is executed immediately. That's what the following means:
(function x() {
console.log('hello');
})();
You can also do:
(function() {
console.log('hello');
}());
IIFEs are commonly used to create a "private" scope for a bit of code so that it plays nice (doesn't conflict) with anything else.
The second function you provided makes more sense and perhaps the first one must have been just an example.
Handlebars allows you to precompile your templates so you don't have to compile them at run-time. Also this way you don't have to make extra HTTP requests just to load the template(s).
For example if I have the following project structure - (note that my models, collections, and views are all within main.js just for this example and all my .js
files are in my root directory):
├── Gruntfile.js
├── handlebars-v2.0.0.js
├── index.html
├── main.js
├── package.json
└── templates
└── todo.handlebars
My todo.handlebars
looks like so - just html with Handlebars syntax:
<h3>{{title}}</h3>
<p>Created by: {{author}}</p>
To precompile my template I would do the following in the command line (you have to install the handlebars precompile script first with: npm install -g handlebars
):
> handlebars templates/todo.handlebars -f todo.tpl.js
Now my project structure looks like so:
├── Gruntfile.js
├── handlebars-v2.0.0.js
├── index.html
├── main.js
├── package.json
├── templates
│ └── todo.handlebars
└── todo.tpl.js
You'll see that a todo.tpl.js
file has been added to my root directory. I could have named it something different if I wanted to as long as the extension is a .js
because the file contains valid JavaScript code. Also I could have specified a different directory to output it to. Remember that the todo.tpl.js
file is the actual template that your Backbone View will use. You write your HTML in todo.handlebars
and compile it as todo.tpl.js
.
Now that I have the todo.tpl.js
file I can use Grunt to maybe concat all my JS template files into a all_templates.js
file or I can reference each file directly in my HTML like so:
<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="http://documentcloud.github.io/underscore/underscore-min.js"></script>
<script src="http://documentcloud.github.io/backbone/backbone-min.js"></script>
<script src="handlebars-v2.0.0.js"></script>
<script src="todo.tpl.js"></script> <!-- My Template for a Todo item -->
<script src="main.js"></script>
In my Backbone View, which in my case lives inside my main.js file, I would get the template like so:
var TodoView = Backbone.View.extend({
tagName: 'li',
className: 'todo-item',
events: {
},
// You can grab your template function with the name you chose when
// you precompiled it from: `Handlebars.templates`
template: Handlebars.templates.todo,
initialize: function(options) {
this.listenTo(this.model, 'change', this.render);
},
render: function() {
this.$el.html(this.template( this.model.toJSON() ));
return this;
}
});
And you're done! More info here:
I have created a simple plugin to achieve this. More information about this: https://github.com/miketimmerman/load-template