From 8b2e284fc32016101ed9fdb1706c3da02c2e42ef Mon Sep 17 00:00:00 2001 From: BennettJames Date: Sun, 7 Feb 2016 22:08:43 -0800 Subject: [PATCH] Added automatic discovery mechanism for partials --- hbs.js | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/hbs.js b/hbs.js index 2cd32c6..131f7c6 100644 --- a/hbs.js +++ b/hbs.js @@ -4,7 +4,49 @@ import Handlebars from 'handlebars'; const handlebarsRuntimePath = System.normalizeSync('handlebars/handlebars.runtime', __moduleName); +/** + * Attaches the precompiled Handlebars template in a CommonJs module, + * and attaches any depended partials on `load` for system.js to + * fetch. Also registers the partials as such on the Handlebars + * runtime. + */ export function translate(load) { - var precompiled = Handlebars.precompile(load.source); - load.source = `module.exports = require('${handlebarsRuntimePath}').template(${precompiled});`; + + let ast = Handlebars.parse(load.source); + let partials = findPartials(ast); + load.metadata.deps = partials; + + let precompiled = Handlebars.precompile(load.source); + let partialReqs = partials.map(dep => + `Handlebars.registerPartial('${dep}', require('${dep}'));`); + + load.source = ` + var Handlebars = require('${handlebarsRuntimePath}'); + ${partialReqs.join('\n')}; + module.exports = Handlebars.template(${precompiled}); + `; +} + +/** + * Recursively trawls a Handlebars AST, providing the string names of + * all invoked partials. + */ +function findPartials(astRoot) { + let partials = []; + + let recurse = function(ast) { + if (!ast) { + return; + } else if (Array.isArray(ast)) { + ast.forEach(n => recurse(n)); + } else if (ast.type === 'PartialStatement') { + partials.push(ast.name.original); + } else if (typeof ast === 'object') { + let subnodes = Object.keys(ast).map(k => ast[k]); + subnodes.forEach(n => recurse(n)); + } + }; + recurse(astRoot); + + return partials; }