Reputation: 647
I'm using Marionette with requirejs and I would also like to use precompiled handlebars templates. How does this work?
Here my current setup:
require_main.js:
requirejs.config({
baseUrl: "/",
paths: {
'text': 'vendor/javascripts/text',
'backbone': "vendor/javascripts/backbone",
'backbone.wreqr': "vendor/javascripts/backbone.wreqr",
'backbone.babysitter': "vendor/javascripts/backbone.babysitter",
'jquery': "vendor/javascripts/jquery",
'jquery-ui': 'vendor/javascripts/jquery-ui',
'json2': "vendor/javascripts/json2",
'marionette': "vendor/javascripts/backbone.marionette",
'underscore': "vendor/javascripts/underscore",
'handlebars': "vendor/javascripts/handlebars"
},
shim: {
'underscore': {
exports: "_"
},
'backbone': {
deps: ["jquery", "underscore", "json2"],
exports: "Backbone"
},
'marionette': {
deps: ["backbone"],
exports: "Marionette"
},
'jquery-ui': ['jquery'],
'handlebars': {
exports: 'Handlebars'
}
}
});
require(["app"], function(MyApp){
MyApp.start();
});
app.js:
define(['marionette', 'handlebars', 'text!compiled.handlebars'], function(Marionette, Handlebars, Template_one) {
var MyApp = new Marionette.Application();
MyApp.addRegions({
mainRegion: "#main-region"
});
MyApp.StaticView = Marionette.ItemView.extend({
template: Template_one(context)
});
MyApp.on("initialize:after", function(){
var staticView = new MyApp.StaticView();
MyApp.mainRegion.show(staticView);
});
});
in my app.js I can get evth. work just fine with non compiled templates, like this:
...
var template = Handlebars.compile(Template_one)
var html = template(context)
template: html
...
but how to do it right with compiled templates?
Upvotes: 3
Views: 6804
Reputation: 4721
The reason I mentioned Grunt
earlier is because it comes very handy for a LOT of things. So, in my opinion, it's very important to know/learn about it.
But you can achieve the exact same thing with the Handlebars precompiler alone:
$ handlebars templates/* -f js/precompiled.handlebars.js
You still have to integrate precompiled.handlebars.js
in your RequireJS config, see at the end of the answer.
You'll need the Grunt Task Runner for that, it makes these kind of things a LOT easier.
From now on, I'm assuming the following folder structure:
project/
assets/
js/
templates/
I'm also assuming you have node.js installed on your machine!
$ cd project/assets/
$ sudo npm install grunt --save-dev
You'll also need the Handlebars Grunt plugin in order to precompile your templates:
Install it like this:
$ sudo npm install grunt-contrib-handlebars --save-dev
Notes:
Gruntfile.js
is a configuration file for GruntCreate the file:
$ touch Gruntfile.js
Then copy/paste this typical Gruntfile
for accomplishing what you want to achieve:
module.exports = function(grunt) {
/*
* https://github.com/gruntjs/grunt/wiki/Configuring-tasks
*/
grunt.initConfig({
"handlebars": {
compile: {
options: {
amd: true
},
src: ["templates/**/*.html"],
dest: "js/precompiled.handlebars.js"
}
}
});
// Requires the needed plugin
grunt.loadNpmTasks('grunt-contrib-handlebars');
};
All plugin options here.
Then, assuming that you have templates living in assets/templates/
, run:
$ grunt handlebars:compile
If everything is ok you should be able to see your compiled templates in js/precompiled.handlebars.js
:
define([
// Should be `handlebars.runtime.js` here
// See: http://handlebarsjs.com/precompilation.html
'handlebars'
], function(Handlebars) {
this["JST"] = this["JST"] || {};
this["JST"]["templates/template_one.html"] = Handlebars.template(function(Handlebars,depth0,helpers,partials,data) { /* ... */ });
this["JST"]["templates/template_two.html"] = Handlebars.template(function(Handlebars,depth0,helpers,partials,data) { /* ... */ });
//...
return this["JST"];
});
Obviously, in your Views
, you'll have to change your dependencies:
define([
'marionette',
//'handlebars', /* You don't need this _here_ anymore */
'js/compiled.handlebars'
], function(Marionette, JST) {
/* edited for brevity */
MyApp.StaticView = Marionette.ItemView.extend({
template: JST["templates/template_one.html"]
});
MyApp.on("initialize:after", function(){
var staticView = new MyApp.StaticView();
MyApp.mainRegion.show(staticView);
});
});
Upvotes: 16