consolidate
Advanced tools
Comparing version 0.14.5 to 0.15.0
@@ -0,1 +1,12 @@ | ||
0.15.0 / 2017-11-01 | ||
=================== | ||
* add plates support | ||
* add teacup support | ||
* add liquid-node support | ||
* add velocityjs support | ||
* allow absolute and relative partial paths | ||
* extend dot options | ||
* support layouts in vash | ||
0.14.0 / 2016-01-24 | ||
@@ -2,0 +13,0 @@ =================== |
@@ -25,2 +25,3 @@ 'use strict'; | ||
var dirname = path.dirname; | ||
var isAbsolute = path.isAbsolute; | ||
@@ -48,2 +49,3 @@ var readCache = {}; | ||
exports.clearCache = function(){ | ||
readCache = {}; | ||
cacheStore = {}; | ||
@@ -123,3 +125,19 @@ }; | ||
var key = keys[index]; | ||
var file = join(dirname(path), partials[key] + extname(path)); | ||
var partialPath = partials[key]; | ||
if (partialPath === undefined || partialPath === null || partialPath === false) { | ||
return next(++index); | ||
} | ||
var file; | ||
if (isAbsolute(partialPath)) { | ||
if (extname(partialPath) !== '') { | ||
file = partialPath; | ||
} else { | ||
file = join(partialPath + extname(path)); | ||
} | ||
} else { | ||
file = join(dirname(path), partialPath + extname(path)); | ||
} | ||
read(file, options, function(err, str){ | ||
@@ -177,2 +195,24 @@ if (err) return fn(err); | ||
/** | ||
* velocity support. | ||
*/ | ||
exports.velocityjs = fromStringRenderer('velocityjs'); | ||
/** | ||
* velocity string support. | ||
*/ | ||
exports.velocityjs.render = function(str, options, fn){ | ||
return promisify(fn, function(fn) { | ||
var engine = requires.velocityjs || (requires.velocityjs = require('velocityjs')); | ||
try { | ||
options.locals = options; | ||
fn(null, engine.render(str, options).trimLeft()); | ||
} catch (err) { | ||
fn(err); | ||
} | ||
}); | ||
}; | ||
/** | ||
* Liquid support. | ||
@@ -195,23 +235,124 @@ */ | ||
function _renderTinyliquid(engine, str, options, fn) { | ||
var context = engine.newContext(); | ||
var k; | ||
/** | ||
* Note that there's a bug in the library that doesn't allow us to pass | ||
* the locals to newContext(), hence looping through the keys: | ||
*/ | ||
if (options.locals) { | ||
for (k in options.locals) { | ||
context.setLocals(k, options.locals[k]); | ||
} | ||
delete options.locals; | ||
} | ||
if (options.meta) { | ||
context.setLocals('page', options.meta); | ||
delete options.meta; | ||
} | ||
/** | ||
* Add any defined filters: | ||
*/ | ||
if (options.filters) { | ||
for (k in options.filters) { | ||
context.setFilter(k, options.filters[k]); | ||
} | ||
delete options.filters; | ||
} | ||
/** | ||
* Set up a callback for the include directory: | ||
*/ | ||
var includeDir = options.includeDir || process.cwd(); | ||
context.onInclude(function (name, callback) { | ||
var extname = path.extname(name) ? '' : '.liquid'; | ||
var filename = path.resolve(includeDir, name + extname); | ||
fs.readFile(filename, {encoding: 'utf8'}, function (err, data) { | ||
if (err) return callback(err); | ||
callback(null, engine.parse(data)); | ||
}); | ||
}); | ||
delete options.includeDir; | ||
/** | ||
* The custom tag functions need to have their results pushed back | ||
* through the parser, so set up a shim before calling the provided | ||
* callback: | ||
*/ | ||
var compileOptions = { | ||
customTags: {} | ||
}; | ||
if (options.customTags) { | ||
var tagFunctions = options.customTags; | ||
for (k in options.customTags) { | ||
/*Tell jshint there's no problem with having this function in the loop */ | ||
/*jshint -W083 */ | ||
compileOptions.customTags[k] = function (context, name, body) { | ||
var tpl = tagFunctions[name](body.trim()); | ||
context.astStack.push(engine.parse(tpl)); | ||
}; | ||
/*jshint +W083 */ | ||
} | ||
delete options.customTags; | ||
} | ||
/** | ||
* Now anything left in `options` becomes a local: | ||
*/ | ||
for (k in options) { | ||
context.setLocals(k, options[k]); | ||
} | ||
/** | ||
* Finally, execute the template: | ||
*/ | ||
var tmpl = cache(context) || cache(context, engine.compile(str, compileOptions)); | ||
tmpl(context, fn); | ||
} | ||
exports.liquid.render = function(str, options, fn){ | ||
return promisify(fn, function (fn) { | ||
var engine = requires.liquid || (requires.liquid = require('tinyliquid')); | ||
var engine = requires.liquid; | ||
var Liquid; | ||
try { | ||
var context = engine.newContext(); | ||
var k; | ||
// set up tinyliquid engine | ||
engine = requires.liquid = require('tinyliquid'); | ||
/** | ||
* Note that there's a bug in the library that doesn't allow us to pass | ||
* the locals to newContext(), hence looping through the keys: | ||
*/ | ||
// use tinyliquid engine | ||
_renderTinyliquid(engine, str, options, fn); | ||
if (options.locals){ | ||
for (k in options.locals){ | ||
context.setLocals(k, options.locals[k]); | ||
} | ||
delete options.locals; | ||
return; | ||
} catch (err) { | ||
// set up liquid-node engine | ||
try { | ||
Liquid = requires.liquid = require('liquid-node'); | ||
engine = new Liquid.Engine; | ||
} catch (err) { | ||
throw err; | ||
} | ||
} | ||
// use liquid-node engine | ||
try { | ||
var locals = options.locals || {}; | ||
if (options.meta){ | ||
context.setLocals('page', options.meta); | ||
locals.pages = options.meta; | ||
delete options.meta; | ||
@@ -224,6 +365,4 @@ } | ||
if (options.filters){ | ||
for (k in options.filters){ | ||
context.setFilter(k, options.filters[k]); | ||
} | ||
if (options.filters) { | ||
engine.registerFilters(options.filters); | ||
delete options.filters; | ||
@@ -237,12 +376,3 @@ } | ||
var includeDir = options.includeDir || process.cwd(); | ||
context.onInclude(function (name, callback) { | ||
var extname = path.extname(name) ? '' : '.liquid'; | ||
var filename = path.resolve(includeDir, name + extname); | ||
fs.readFile(filename, {encoding: 'utf8'}, function (err, data){ | ||
if (err) return callback(err); | ||
callback(null, engine.parse(data)); | ||
}); | ||
}); | ||
engine.fileSystem = new Liquid.LocalFileSystem(includeDir, 'liquid'); | ||
delete options.includeDir; | ||
@@ -264,9 +394,3 @@ | ||
for (k in options.customTags){ | ||
/*Tell jshint there's no problem with having this function in the loop */ | ||
/*jshint -W083 */ | ||
compileOptions.customTags[k] = function (context, name, body){ | ||
var tpl = tagFunctions[name](body.trim()); | ||
context.astStack.push(engine.parse(tpl)); | ||
}; | ||
/*jshint +W083 */ | ||
engine.registerTag(k, tagFunctions[k]); | ||
} | ||
@@ -280,4 +404,4 @@ delete options.customTags; | ||
for (k in options){ | ||
context.setLocals(k, options[k]); | ||
for (var k in options){ | ||
locals[k] = options[k]; | ||
} | ||
@@ -289,4 +413,12 @@ | ||
var tmpl = cache(context) || cache(context, engine.compile(str, compileOptions)); | ||
tmpl(context, fn); | ||
return engine | ||
.parseAndRender(str, locals) | ||
.nodeify(function (err, result) { | ||
if (err) { | ||
throw new Error(err); | ||
} else { | ||
return fn(null, result); | ||
} | ||
}); | ||
} catch (err) { | ||
@@ -396,3 +528,8 @@ fn(err); | ||
try { | ||
var tmpl = cache(options) || cache(options, engine.compileFn(str)); | ||
var templateName; | ||
if (options.filename) { | ||
templateName = options.filename.replace(new RegExp('^' + views + '/'), '').replace(new RegExp('\\.' + ext), ''); | ||
} | ||
var tmpl = cache(options) || cache(options, engine.compileFn(str, templateName)); | ||
tmpl(options, fn); | ||
@@ -417,3 +554,14 @@ } catch (err) { | ||
return promisify(fn, function(fn) { | ||
var engine = requires.swig || (requires.swig = require('swig')); | ||
var engine = requires.swig; | ||
if (!engine) { | ||
try { | ||
engine = requires.swig = require('swig'); | ||
} catch (err) { | ||
try { | ||
engine = requires.swig = require('swig-templates'); | ||
} catch (otherError) { | ||
throw err; | ||
} | ||
} | ||
} | ||
@@ -1043,4 +1191,8 @@ try { | ||
var engine = requires.dot || (requires.dot = require('dot')); | ||
var extend = (requires.extend || (requires.extend = require('util')._extend)); | ||
try { | ||
var tmpl = cache(options) || cache(options, engine.compile(str, options && options._def)); | ||
var settings = {}; | ||
settings = extend(settings, engine.templateSettings); | ||
settings = extend(settings, options ? options.dot : {}); | ||
var tmpl = cache(options) || cache(options, engine.template(str, settings, options)); | ||
fn(null, tmpl(options)); | ||
@@ -1067,3 +1219,3 @@ } catch (err) { | ||
try { | ||
var tmpl = cache(options) || cache(options, engine.default.compile(str)); | ||
var tmpl = cache(options) || cache(options, engine.default.compile(str, options)); | ||
fn(null, tmpl(options)); | ||
@@ -1278,5 +1430,28 @@ } catch (err) { | ||
/** | ||
* Plates Support. | ||
*/ | ||
exports.plates = fromStringRenderer('plates'); | ||
/** | ||
* Plates string support. | ||
*/ | ||
exports.plates.render = function(str, options, fn) { | ||
return promisify(fn, function (fn) { | ||
var engine = requires.plates || (requires.plates = require('plates')); | ||
var map = options.map || undefined; | ||
try { | ||
var tmpl = engine.bind(str, options, map); | ||
fn(null, tmpl); | ||
} catch (err) { | ||
fn(err); | ||
} | ||
}); | ||
} | ||
/** | ||
* The main render parser for React bsaed templates | ||
@@ -1330,3 +1505,9 @@ */ | ||
// Parsing | ||
Code = (type === 'path') ? require(resolve(str)) : requireReactString(str); | ||
if (type === 'path') { | ||
var path = resolve(str) | ||
delete require.cache[path] | ||
Code = require(path) | ||
} else { | ||
Code = requireReactString(str) | ||
} | ||
Factory = cache(options, react.createFactory(Code)); | ||
@@ -1429,4 +1610,8 @@ | ||
} | ||
var tmpl = cache(options) || cache(options, engine.compile(str, options)); | ||
fn(null, tmpl(options).replace(/\n$/, '')); | ||
tmpl(options, function sealLayout(err, ctx) { | ||
ctx.finishLayout(); | ||
fn(null, ctx.toString().replace(/\n$/, '')); | ||
}); | ||
} catch (err) { | ||
@@ -1472,3 +1657,3 @@ fn(err); | ||
var tmpl = cache(options) || cache(options, engine.load(path, options)); | ||
tmpl.render(options, fn) | ||
tmpl.renderToString(options, fn) | ||
} catch (err) { | ||
@@ -1488,6 +1673,7 @@ fn(err); | ||
options.writeToDisk = !!options.cache; | ||
options.filename = options.filename || 'string.marko'; | ||
try { | ||
var tmpl = cache(options) || cache(options, engine.load('string.marko', str, options)); | ||
tmpl.render(options, fn) | ||
var tmpl = cache(options) || cache(options, engine.load(options.filename, str, options)); | ||
tmpl.renderToString(options, fn) | ||
} catch (err) { | ||
@@ -1500,5 +1686,42 @@ fn(err); | ||
/** | ||
* Teacup support. | ||
*/ | ||
exports.teacup = function(path, options, fn) { | ||
return promisify(fn, function(fn) { | ||
var engine = requires.teacup || (requires.teacup = require('teacup/lib/express')); | ||
require.extensions['.teacup'] = require.extensions['.coffee']; | ||
if (path[0] != '/') { | ||
path = join(process.cwd(), path); | ||
} | ||
if (!options.cache) { | ||
var originalFn = fn; | ||
fn = function() { | ||
delete require.cache[path]; | ||
originalFn.apply(this, arguments); | ||
}; | ||
} | ||
engine.renderFile(path, options, fn); | ||
}); | ||
}; | ||
/** | ||
* Teacup string support. | ||
*/ | ||
exports.teacup.render = function(str, options, fn){ | ||
var coffee = require('coffee-script'); | ||
var vm = require('vm'); | ||
var sandbox = { | ||
module: {exports: {}}, | ||
require: require | ||
}; | ||
return promisify(fn, function(fn) { | ||
vm.runInNewContext(coffee.compile(str), sandbox); | ||
var tmpl = sandbox.module.exports; | ||
fn(null, tmpl(options)); | ||
}); | ||
} | ||
/** | ||
* expose the instance of the engine | ||
*/ | ||
exports.requires = requires; | ||
exports.requires = requires; |
{ | ||
"name": "consolidate", | ||
"description": "Template engine consolidation library", | ||
"version": "0.14.5", | ||
"version": "0.15.0", | ||
"author": "TJ Holowaychuk <tj@vision-media.ca>", | ||
"license": "MIT", | ||
"main": "index", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/visionmedia/consolidate.js.git" | ||
}, | ||
"dependencies": { | ||
@@ -14,3 +20,4 @@ "bluebird": "^3.1.1" | ||
"babel-preset-react": "^6.5.0", | ||
"bracket-template": "^1.0.3", | ||
"bracket-template": "^1.1.4", | ||
"coffee-script": "^1.11.1", | ||
"dot": "^1.0.1", | ||
@@ -37,2 +44,3 @@ "dust": "^0.3.0", | ||
"just": "^0.1.8", | ||
"liquid-node": "^2.6.1", | ||
"liquor": "^0.0.5", | ||
@@ -45,2 +53,3 @@ "lodash": "^4.0.0", | ||
"nunjucks": "^3.0.0", | ||
"plates": "~0.4.8", | ||
"pug": "^2.0.0-beta6", | ||
@@ -53,5 +62,7 @@ "qejs": "^3.0.5", | ||
"slm": "^0.5.0", | ||
"swig-templates": "^2.0.2", | ||
"swig": "^1.4.1", | ||
"teacup": "^2.0.0", | ||
"templayed": ">=0.2.3", | ||
"tinyliquid": "^0.2.22", | ||
"tinyliquid": "^0.2.30", | ||
"toffee": "^0.1.12", | ||
@@ -62,3 +73,4 @@ "twig": "^0.10.0", | ||
"walrus": "^0.10.1", | ||
"whiskers": "^0.4.0" | ||
"whiskers": "^0.4.0", | ||
"velocityjs": "^0.8.2" | ||
}, | ||
@@ -70,8 +82,2 @@ "keywords": [ | ||
], | ||
"license": "MIT", | ||
"main": "index", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/visionmedia/consolidate.js.git" | ||
}, | ||
"scripts": { | ||
@@ -78,0 +84,0 @@ "test": "mocha" |
@@ -35,2 +35,3 @@ # Consolidate.js | ||
- [nunjucks](https://github.com/mozilla/nunjucks) [(website)](https://mozilla.github.io/nunjucks) | ||
- [plates](https://github.com/flatiron/plates) | ||
- [pug (formerly jade)](https://github.com/pugjs/pug) [(website)](http://jade-lang.com/) | ||
@@ -42,2 +43,4 @@ - [QEJS](https://github.com/jepso/QEJS) | ||
- [swig (unmaintained)](https://github.com/paularmstrong/swig) | ||
- [swig (maintained fork)](https://github.com/node-swig/swig-templates) | ||
- [teacup](https://github.com/goodeggs/teacup) | ||
- [templayed](http://archan937.github.com/templayed.js/) | ||
@@ -108,12 +111,6 @@ - [twig](https://github.com/justjohn/twig.js) | ||
To enable or disable caching simply pass `{ cache: true/false }`. Engines _may_ use this option to cache things reading the file contents, compiled `Function`s etc. Engines which do _not_ support this may simply ignore it. All engines that consolidate.js implements I/O for will cache the file contents, ideal for production environments. | ||
To enable caching simply pass `{ cache: true }`. Engines _may_ use this option to cache things reading the file contents, compiled `Function`s etc. Engines which do _not_ support this may simply ignore it. All engines that consolidate.js implements I/O for will cache the file contents, ideal for production environments. | ||
When using consolidate directly: `cons.swig('views/page.html', { user: 'tobi', cache:true }, callback);` | ||
Using Express 3 or higher: `app.locals.cache = true` or set NODE_ENV to 'production' and Express will do this for you. | ||
```js | ||
var cons = require('consolidate'); | ||
cons.swig('views/page.html', { cache: false, user: 'tobi' }, function(err, html){ | ||
if (err) throw err; | ||
console.log(html); | ||
}); | ||
``` | ||
## Express 3.x example | ||
@@ -120,0 +117,0 @@ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
52478
1400
55
211
4