Skip to content

Instantly share code, notes, and snippets.

@garth
Forked from wagenet/Assetfile.rb
Created January 16, 2012 18:37
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save garth/1622236 to your computer and use it in GitHub Desktop.
Save garth/1622236 to your computer and use it in GitHub Desktop.
Precompile .handlebars templates with Jake (nodejs)
var fs = require('fs')
var vm = require('vm')
var handlebarsjs = fs.readFileSync('path/to/handlebars.js', 'utf8')
var emberjs = fs.readFileSync('path/to/ember.js', 'utf8')
var templatesDir = 'path/to/template/dir'
desc('Compile all .handlebars templates')
task({ 'handlebars': [] }, function () {
process.stdout.write('Compiling .handlebars templates')
var files = fs.readdirSync(templatesDir)
var i
for (i = 0; i < files.length; i++) {
if (/\.handlebars$/.test(files[i])) {
compileHandlebarsTemplate(templatesDir + '/' + files[i])
process.stdout.write('.')
}
}
console.log('done')
})
function compileHandlebarsTemplate(file, onComplete) {
//dummy jQuery
var jQuery = function () { return jQuery }
jQuery.ready = function () { return jQuery }
jQuery.inArray = function () { return jQuery }
jQuery.jquery = "1.7.1"
jQuery.event = { fixHooks: {} }
//dummy DOM element
var element = {
firstChild: function () { return element },
innerHTML: function () { return element }
}
var sandbox = {
// DOM
document: {
createRange: false,
createElement: function () { return element }
},
// Console
console: console,
// jQuery
jQuery: jQuery,
$: jQuery,
// handlebars template to compile
template: fs.readFileSync(file, 'utf8'),
// compiled handlebars template
templatejs: null
}
// window
sandbox.window = sandbox
// create a context for the vm using the sandbox data
var context = vm.createContext(sandbox)
// load Handlebars and Ember into the sandbox
vm.runInContext(handlebarsjs, context, 'ember.js')
vm.runInContext(emberjs, context, 'ember.js')
//compile the handlebars template inside the vm context
vm.runInContext('templatejs = Ember.Handlebars.precompile(template).toString()', context)
var fileName = path.basename(file)
var namedTemplateJs = 'Ember.TEMPLATES["' +
fileName.replace(/.handlebars/, '') +
'"] = Ember.Handlebars.template(' + context.templatejs + ');'
//extract the compiled template from the vm context and save to .js file,
//implicitely adding template to Ember.TEMPLATES when it is required
fs.writeFileSync(file.replace(/\.handlebars$/, '.js'), namedTemplateJs, 'utf8')
}
@garth
Copy link
Author

garth commented Jan 16, 2012

  • This is an extraction of a larger jakefile (https://github.com/mde/jake) so I hope I haven't missed anything.
  • The compileHandlebarsTemplate function should work without jake.
  • This sample could be more efficient, especially if emberjs is not re-evaluated on each call, but it seems fast enough.
  • Unlike the original example by @wagenet this sample will compile each .handlebars file to its own .js file (this is better for my build workflow), if you want to merge all output to a single file then it should be easy to modify.

@garth
Copy link
Author

garth commented Jul 17, 2012

Added line:

jQuery.event = { fixHooks: {} }

to fix recently introduced emberjs dependency on jQuery.event object.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment