Skip to content

Commit

Permalink
Fixed Nunjucks rendering engine to properly support options per #152
Browse files Browse the repository at this point in the history
  • Loading branch information
niftylettuce committed Nov 11, 2016
1 parent 1ac7052 commit 12c19d9
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 70 deletions.
20 changes: 20 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"extends": "standard",
"rules": {
"padded-blocks": 0,
"semi": 0,
"curly": 0,
"space-before-function-paren": 0,
"space-before-blocks": 0,
"brace-style": 0,
"quotes": 0,
"new-cap": 0,
"no-multiple-empty-lines": 0,
"promise/param-names": 0,
"spaced-comment": 0,
"yoda": 0,
"keyword-spacing": 0,
"standard/object-curly-even-spacing": 0,
"comma-spacing": 0
}
}
1 change: 1 addition & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ cons.requires.nunjucks.addFilter('foo', function () {

## Notes

* If you're using Nunjucks, please take a look at the `exports.nunjucks.render` function in `lib.consolidate.js`. You can pass your own engine/environment via `options.nunjucksEnv`, or if you want to support Express you can pass `options.settings.views`, or if you have another use case, pass `options.nunjucks` (see the code for more insight).
* You can pass **partials** with `options.partials`
* For using **template inheritance** with nunjucks, you can pass a loader
with `options.loader`.
Expand Down
157 changes: 106 additions & 51 deletions lib/consolidate.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@
* Module dependencies.
*/

var fs = require('fs')
, path = require('path')
, join = path.join
, resolve = path.resolve
, extname = path.extname
, Promise = require('bluebird')
, dirname = path.dirname;
var fs = require('fs');
var path = require('path');
var Promise = require('bluebird');

var join = path.join;
var resolve = path.resolve;
var extname = path.extname;
var dirname = path.dirname;

var readCache = {};

Expand Down Expand Up @@ -365,8 +366,8 @@ exports.dust.render = function(str, options, fn){
}
}

var ext = 'dust'
, views = '.';
var ext = 'dust';
var views = '.';

if (options) {
if (options.ext) ext = options.ext;
Expand Down Expand Up @@ -856,9 +857,9 @@ exports.qejs.render = function (str, options, fn) {
try {
var engine = requires.qejs || (requires.qejs = require('qejs'));
engine.render(str, options).then(function (result) {
fn(null, result);
fn(null, result);
}, function (err) {
fn(err);
fn(err);
}).done();
} catch (err) {
fn(err);
Expand Down Expand Up @@ -1032,7 +1033,7 @@ exports.dot.render = function (str, options, fn) {
fn(null, tmpl(options));
} catch (err) {
fn(err);
}
}
});
};

Expand Down Expand Up @@ -1064,8 +1065,8 @@ exports.ractive.render = function(str, options, fn){
var i, length;
var properties = ["template", "filename", "cache", "partials"];
for (i = 0, length = properties.length; i < length; i++) {
var property = properties[i];
delete options.data[property];
var property = properties[i];
delete options.data[property];
}
}

Expand All @@ -1087,19 +1088,69 @@ exports.nunjucks = fromStringRenderer('nunjucks');
* Nunjucks string support.
*/

exports.nunjucks.render = function(str, options, fn) {
exports.nunjucks.render = function (str, options, fn) {
return promisify(fn, function (fn) {

try {
var engine = requires.nunjucks || (requires.nunjucks = require('nunjucks'));
if (options.settings && options.settings.views) engine.configure(options.settings.views);

var engine = options.nunjucksEnv || requires.nunjucks || (requires.nunjucks = require('nunjucks'));

var env = engine;

// deprecated fallback support for express
// <https://github.com/tj/consolidate.js/pull/152>
// <https://github.com/tj/consolidate.js/pull/224>
if (options.settings && options.settings.views)
env = engine.configure(options.settings.views);
else if (options.nunjucks && options.nunjucks.configure)
env = engine.configure.apply(engine, options.nunjucks.configure);

//
// because `renderString` does not initiate loaders
// we must manually create a loader for it based off
// either `options.settings.views` or `options.nunjucks` or `options.nunjucks.root`
//
// <https://github.com/mozilla/nunjucks/issues/730>
// <https://github.com/crocodilejs/node-email-templates/issues/182>
//

//
// note that the below code didn't work nor make sense before
// because loaders should take different options from rendering
//

/*
var loader = options.loader;
if (loader) {
var env = new engine.Environment(new loader(options));
env.renderString(str, options, fn);
} else {
engine.renderString(str, options, fn);
}
*/

// so instead we simply check if we passed a custom loader
// otherwise we create a simple file based loader
if (options.loader) {
env = new engine.Environment(options.loader);
} else if (options.settings && options.settings.views) {
env = new engine.Environment(
new engine.FileSystemLoader(options.settings.views)
);
} else if (options.nunjucks && options.nunjucks.loader) {
if (typeof options.nunjucks.loader === 'string')
env = new engine.Environment(new engine.FileSystemLoader(options.nunjucks.loader));
else
env = new engine.Environment(
new engine.FileSystemLoader(
options.nunjucks.loader[0],
options.nunjucks.loader[1]
)
);
}

env.renderString(str, options, fn);

} catch (err) {
throw fn(err);
}
Expand Down Expand Up @@ -1149,6 +1200,9 @@ exports.requireReact = requireReact;
* Converting a string into a node module.
*/
function requireReactString(src, filename) {

if (!filename) filename = '';

var tools = requires.reactTools || (requires.reactTools = require('react-tools'));
var m = new module.constructor();

Expand All @@ -1167,14 +1221,15 @@ function requireReactString(src, filename) {
* A naive helper to replace {{tags}} with options.tags content
*/
function reactBaseTmpl(data, options){
var exp,
regex;

var exp;
var regex;

// Iterates through the keys in file object
// and interpolate / replace {{key}} with it's value
for (var k in options){
if (options.hasOwnProperty(k)){
exp = '{{'+k+'}}';
exp = '{{' + k + '}}';
regex = new RegExp(exp, 'g');
if (data.match(regex)) {
data = data.replace(regex, options[k]);
Expand All @@ -1191,27 +1246,29 @@ function reactBaseTmpl(data, options){
* The main render parser for React bsaed templates
*/
function reactRenderer(type){

if (require.extensions) {

// Ensure JSX is transformed on require
if (!require.extensions['.jsx']) {
require.extensions['.jsx'] = requireReact;
}

// Supporting .react extension as well as test cases
// Using .react extension is not recommended.
if (!require.extensions['.react']) {
require.extensions['.react'] = requireReact;
}

}

// Return rendering fx
return function(str, options, fn) {
return promisify(fn, function(fn) {
// React Import
var engine = requires.react || (requires.react = require('react'));

var ReactDOM = requires.ReactDOM || (requires.ReactDOM = require('react-dom/server'));
var react = requires.react || (requires.react = require('react'));

// Assign HTML Base
var base = options.base;
Expand All @@ -1226,24 +1283,24 @@ function reactRenderer(type){
// Start Conversion
try {

var Code,
Factory;
var Code;
var Factory;

var baseStr,
content,
parsed;
var baseStr;
var content;
var parsed;

if (!cache(options)){
// Parsing
Code = (type === 'path') ? require(resolve(str)) : requireReactString(str);
Factory = cache(options, engine.createFactory(Code));
Factory = cache(options, react.createFactory(Code));

} else {
Factory = cache(options);
}

parsed = new Factory(options);
content = (isNonStatic) ? engine.renderToString(parsed) : engine.renderToStaticMarkup(parsed);
content = (isNonStatic) ? ReactDOM.renderToString(parsed) : ReactDOM.renderToStaticMarkup(parsed);

if (base){
baseStr = readCache[str] || fs.readFileSync(resolve(base), 'utf8');
Expand Down Expand Up @@ -1320,27 +1377,25 @@ exports.vash = fromStringRenderer('vash');
* Vash string support
*/
exports.vash.render = function(str, options, fn) {
return promisify(fn, function(fn) {
var engine = requires.vash || (requires.vash = require('vash'));
return promisify(fn, function(fn) {
var engine = requires.vash || (requires.vash = require('vash'));

try {
// helper system : https://github.com/kirbysayshi/vash#helper-system
if (options.helpers) {
for (var key in options.helpers) {
if (!options.helpers.hasOwnProperty(key) || typeof options.helpers[key] !== 'function') {
continue;
}

engine.helpers[key] = options.helpers[key];
}
}

var tmpl = cache(options) || cache(options, engine.compile(str, options));
fn(null, tmpl(options).replace(/\n$/, ''));
} catch (err) {
fn(err);
try {
// helper system : https://github.com/kirbysayshi/vash#helper-system
if (options.helpers) {
for (var key in options.helpers) {
if (!options.helpers.hasOwnProperty(key) || typeof options.helpers[key] !== 'function') {
continue;
}
engine.helpers[key] = options.helpers[key];
}
});
}
var tmpl = cache(options) || cache(options, engine.compile(str, options));
fn(null, tmpl(options).replace(/\n$/, ''));
} catch (err) {
fn(err);
}
});
};

/**
Expand Down
43 changes: 24 additions & 19 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
{
"name": "consolidate",
"version": "0.14.1",
"description": "Template engine consolidation library",
"keywords": [
"template",
"engine",
"view"
],
"version": "0.14.1",
"author": "TJ Holowaychuk <tj@vision-media.ca>",
"dependencies": {
"bluebird": "^3.1.1"
},
"devDependencies": {
"arc-templates": "^0.5.1",
"atpl": ">=0.7.6",
Expand All @@ -18,6 +16,10 @@
"eco": "^1.1.0-rc-3",
"ect": "^0.5.9",
"ejs": "^2.3.4",
"eslint": "^3.7.1",
"eslint-config-standard": "^6.2.0",
"eslint-plugin-promise": "^3.3.1",
"eslint-plugin-standard": "^2.0.1",
"haml-coffee": "^1.4.0",
"hamlet": "^0.3.3",
"hamljs": "^0.6.1",
Expand All @@ -26,41 +28,44 @@
"htmling": "^0.0.7",
"jade": "^1.9.1",
"jazz": "^0.0.18",
"jqtpl": "^1.1.0",
"jqtpl": "~1.1.0",
"just": "^0.1.8",
"liquor": "^0.0.5",
"lodash": "^4.0.0",
"mocha": "^2.3.4",
"mocha": "^3.1.2",
"mote": "^0.2.0",
"mustache": "^2.2.1",
"nunjucks": "^2.3.0",
"pug": "^0.1.0",
"nunjucks": "^3.0.0",
"pug": "^2.0.0-beta6",
"qejs": "^3.0.5",
"ractive": "^0.6.1",
"react": "^0.14.6",
"ractive": "^0.8.4",
"react": "^15.3.2",
"react-dom": "^15.3.2",
"react-tools": "^0.13.0",
"should": "*",
"slm": "^0.5.0",
"swig": "^1.4.1",
"templayed": ">=0.2.3",
"tinyliquid": "^0.2.22",
"toffee": "^0.1.12",
"twig": "^0.8.2",
"twig": "^0.10.0",
"underscore": "^1.3.3",
"vash": "^0.8.7",
"vash": "^0.12.2",
"walrus": "^0.10.1",
"whiskers": "^0.3.3"
"whiskers": "^0.4.0"
},
"keywords": [
"engine",
"template",
"view"
],
"license": "MIT",
"main": "index",
"repository": {
"type": "git",
"url": "https://github.com/visionmedia/consolidate.js.git"
},
"license": "MIT",
"scripts": {
"test": "mocha"
},
"dependencies": {
"bluebird": "^3.1.1"
}
}

0 comments on commit 12c19d9

Please sign in to comment.