Last active
August 29, 2015 14:17
-
-
Save lennerd/78fe961391c20c1ba6ed to your computer and use it in GitHub Desktop.
Browserify Transformer for Nunjucks Templates
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var through = require('through'), | |
path = require('path'), | |
nunjucks = require('nunjucks'), | |
appRootPath = require('app-root-path').path, | |
_ = require('underscore'); | |
var getTemplateReg = /env\.getTemplate\(("(.*?)")/g; | |
/** | |
* Calculates the templates path relative to the app root path. | |
*/ | |
function templatePath(templatePath) { | |
return path.relative(appRootPath, templatePath); | |
} | |
/** | |
* Browserify transformer for nunjucks templates | |
*/ | |
function nunjucksify(file, options) { | |
var data, extension; | |
options = options || {}; | |
extension = options.extension || ['.nunj']; | |
if (!Array.isArray(extension)) | |
extension = [extension]; | |
// Check for nunjucks template extension for skipping other content types | |
if (!_.contains(extension, path.extname(file))) | |
return through(); | |
// The options hash gets directly passed to the nunjucks.precompileString function. | |
// The name option must be fixed to be unique in the precompiling process. | |
options = _.extend({ | |
asFunction: true | |
}, options, { | |
name: templatePath(file) | |
}); | |
data = ''; | |
function write(buf) { | |
data += buf; | |
} | |
function buildModule(compiledTemplate) { | |
var module = [], requiredTemplates, requires; | |
if (options.asFunction) { | |
requiredTemplates = {}; | |
// options.asFunction is true, so we need the nunjucks module for rendering inside the built module | |
module.push('var nunjucks = require(\'nunjucks\');'); | |
compiledTemplate = compiledTemplate.replace(getTemplateReg, function(fullMatch, strMatch, pathMatch) { | |
var resolvedTemplatePath = templatePath(path.resolve(path.dirname(file), pathMatch)); | |
// Store the template paths in the requiredPaths data set for later use. | |
requiredTemplates[resolvedTemplatePath] = pathMatch; | |
// Replace the getTemplate function call parameter (template file path) with our unique template path. | |
return fullMatch.replace(pathMatch, resolvedTemplatePath); | |
}); | |
// Build the require statements for the needed templates to be known to browserify. | |
requires = _.values(requiredTemplates).map(function(path) { | |
return 'require(\'' + path + '\');'; | |
}); | |
// Do we have any required templates? Add them as simple statements to the generated module. | |
if (requires.length > 0) | |
module.push.apply(module, requires); | |
module.push(compiledTemplate); | |
} else { | |
compiledTemplate = compiledTemplate.replace(getTemplateReg, function(fullMatch, strMatch) { | |
return fullMatch.replace(strMatch, 'require(' + strMatch + ')'); | |
}); | |
// options.asFunction is false, so we need to return the absolute template name to be able to use it inside | |
// other modules | |
module.push(compiledTemplate); | |
module.push('module.exports = \'' + options.name + '\';'); | |
} | |
return module.join('\n'); | |
} | |
function end() { | |
var template = nunjucks.precompileString(data, options); | |
this.queue(buildModule(template)); | |
this.queue(null); | |
} | |
return through(write, end); | |
} | |
module.exports = nunjucksify; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment