#!/usr/bin/env node var optimist = require('optimist') .usage('Precompile handlebar templates.\nUsage: $0 template...', { 'f': { 'type': 'string', 'description': 'Output File', 'alias': 'output' }, 'k': { 'type': 'string', 'description': 'Known helpers', 'alias': 'known' }, 'o': { 'type': 'boolean', 'description': 'Known helpers only', 'alias': 'knownOnly' }, 'm': { 'type': 'boolean', 'description': 'Minimize output', 'alias': 'min' }, 's': { 'type': 'boolean', 'description': 'Output template function only.', 'alias': 'simple' }, 'r': { 'type': 'string', 'description': 'Template root. Base value that will be stripped from template names.', 'alias': 'root' } }) .check(function(argv) { var template = [0]; if (!argv._.length) { throw 'Must define at least one template or directory.'; } argv._.forEach(function(template) { try { fs.statSync(template); } catch (err) { throw 'Unable to open template file "' + template + '"'; } }); }) .check(function(argv) { if (argv.simple && argv.min) { throw 'Unable to minimze simple output'; } if (argv.simple && (argv._.length !== 1 || fs.statSync(argv._[0]).isDirectory())) { throw 'Unable to output multiple templates in simple mode'; } }); var fs = require('fs'), handlebars = require('../lib/handlebars'), basename = require('path').basename, uglify = require('uglify-js'); var argv = optimist.argv, template = argv._[0]; // Convert the known list into a hash var known = {}; if (argv.known && !Array.isArray(argv.known)) { argv.known = [argv.known]; } if (argv.known) { for (var i = 0, len = argv.known.length; i < len; i++) { known[argv.known[i]] = true; } } var output = []; if (!argv.simple) { output.push('(function() {\n var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};\n'); } function processTemplate(template, root) { var path = template, stat = fs.statSync(path); if (stat.isDirectory()) { fs.readdirSync(template).map(function(file) { var path = template + '/' + file; if (/\.handlebars$/.test(path) || fs.statSync(path).isDirectory()) { processTemplate(path, root || template); } }); } else { var data = fs.readFileSync(path, 'utf8'); var options = { knownHelpers: known, knownHelpersOnly: argv.o }; // Clean the template name if (!root) { template = basename(template); } else if (template.indexOf(root) === 0) { template = template.substring(root.length+1); } template = template.replace(/\.handlebars$/, ''); if (argv.simple) { output.push(handlebars.precompile(data, options) + '\n'); } else { output.push('templates[\'' + template + '\'] = template(' + handlebars.precompile(data, options) + ');\n'); } } } argv._.forEach(function(template) { processTemplate(template, argv.root); }); // Output the content if (!argv.simple) { output.push('})();'); } output = output.join(''); if (argv.min) { var ast = uglify.parser.parse(output); ast = uglify.uglify.ast_mangle(ast); ast = uglify.uglify.ast_squeeze(ast); output = uglify.uglify.gen_code(ast); } if (argv.output) { fs.writeFileSync(argv.output, output, 'utf8'); } else { console.log(output); }