templates
Advanced tools
Comparing version 0.19.0 to 0.20.0
@@ -0,1 +1,24 @@ | ||
### v0.20.0 | ||
**Context** | ||
- In general, context should be merged so that the most specific context wins over less specific. This fixes one case where locals was winning over front-matter | ||
**Helpers** | ||
- Exposes `.ctx()` method on helper context, to simplify merging context in non-built-in helpers | ||
**Engines** | ||
- Fixes bug that was using default engine on options instead of engine that matches view file extension. | ||
### v0.19.0 | ||
- Numerous [dependency updates](https://github.com/jonschlinkert/templates/commit/6f78d88aa1920b84d20177bf35942e596b8e58b5) | ||
### v0.18.0 | ||
- [Fixes inheritance bug](https://github.com/jonschlinkert/templates/commit/66b0d885648600c97b4a158eaebf3e95443ec66e) that only manifests in node v0.4.0 | ||
- Improved [error handling in routes](https://github.com/jonschlinkert/templates/commit/d7654b74502465587da1e490c09e486fbf43f6db) | ||
### v0.17.0 | ||
@@ -10,2 +33,3 @@ | ||
- Improved context handling | ||
- Ensure collection middleware is handled [after app middleware](https://github.com/jonschlinkert/templates/commit/f47385f5172a2773c3ab2a969ebfccc533ec5e27) | ||
@@ -12,0 +36,0 @@ ### v0.15.0 |
28
index.js
@@ -301,4 +301,4 @@ /*! | ||
// create aliases on the collection for addView/addViews | ||
// to support chaining | ||
// create aliases on the collection for | ||
// addView/addViews to support chaining | ||
collection.define(plural, this[plural]); | ||
@@ -359,16 +359,4 @@ collection.define(single, this[single]); | ||
/** | ||
* Expose constructors as static methods. | ||
*/ | ||
Templates.Base = Base; | ||
Templates.Item = Item; | ||
Templates.View = View; | ||
Templates.List = List; | ||
Templates.Collection = Collection; | ||
Templates.Views = Views; | ||
Templates.Group = Group; | ||
/** | ||
* Expose static `setup` method for providing access to an | ||
* instance before any other use code is run. | ||
* instance before any other code is run. | ||
* | ||
@@ -396,6 +384,12 @@ * ```js | ||
/** | ||
* Expose package metadata | ||
* Expose constructors as static methods. | ||
*/ | ||
utils.define(Templates, 'meta', require('./package')); | ||
utils.define(Templates, 'Base', Base); | ||
utils.define(Templates, 'Item', Item); | ||
utils.define(Templates, 'View', View); | ||
utils.define(Templates, 'List', List); | ||
utils.define(Templates, 'Collection', Collection); | ||
utils.define(Templates, 'Views', Views); | ||
utils.define(Templates, 'Group', Group); | ||
@@ -402,0 +396,0 @@ /** |
@@ -47,6 +47,6 @@ 'use strict'; | ||
var ctx = helperContext.call(this, view, locals, opts); | ||
debug('"%s" pre-rendering "%s"', single, name); | ||
view.render(ctx, function(err, res) { | ||
view._context = this.ctx(view, locals, opts); | ||
view.render(function(err, res) { | ||
if (err) return cb(err); | ||
@@ -75,42 +75,5 @@ | ||
var hash = options.hash || locals.hash || {}; | ||
var opts = utils.extend({}, this.options, hash); | ||
var opts = utils.merge({}, this.options, hash); | ||
opts.hash = hash; | ||
return opts; | ||
} | ||
/** | ||
* Create the context to use for rendering from: | ||
* | ||
* - helper `locals` | ||
* - helper `options` | ||
* - context (`this.context`) | ||
* - `options.hash` if it's registered as a handlebars helper | ||
* - `view.locals`: locals defined on the view being rendered | ||
* - `view.data`: data from front-matter | ||
* | ||
* @param {Object} `view` the view being rendered | ||
* @param {Object} `locals` Helper locals | ||
* @param {Object} `options` Helper options | ||
* @return {Object} | ||
*/ | ||
function helperContext(view, locals, options) { | ||
var fn = this.options.helperContext; | ||
var extend = utils.extend; | ||
var context = {}; | ||
if (typeof fn === 'function') { | ||
context = fn.call(this, view, locals, options); | ||
} else { | ||
// helper context | ||
context = extend({}, this.view.data); | ||
context = extend({}, context, this.context); | ||
// view context | ||
context = extend({}, context, view.locals, view.data); | ||
// helper locals and options | ||
context = extend({}, context, locals, options.hash); | ||
} | ||
return context; | ||
} |
@@ -74,3 +74,3 @@ 'use strict'; | ||
app.define('bindHelpers', function(view, locals, context, isAsync) { | ||
app.define('bindHelpers', function(view, context, isAsync) { | ||
debug.context('binding helpers for %s <%s>', view.options.inflection, view.basename); | ||
@@ -92,4 +92,4 @@ var optsHelpers = utils.isObject(this.options.helpers) ? this.options.helpers : {}; | ||
// create the context to expose as `this` inside helper functions | ||
var thisArg = new Context(this, view, locals, context, helpers); | ||
// create the "helper context" to be exposed as `this` inside helper functions | ||
var thisArg = new Context(this, view, context, helpers); | ||
@@ -134,13 +134,13 @@ // bind the context to helpers. | ||
* // 'this.helper' => helper name and options | ||
* // 'this.context' => template context (as opposed to _helper_ context) | ||
* // 'this.options' => merged options from app, view, and helper options | ||
* // 'this.context' => view context (as opposed to _helper_ context) | ||
* // 'this.options' => options created for the specified helper being called | ||
* }); | ||
* ``` | ||
* @param {Object} `app` | ||
* @param {Object} `view` | ||
* @param {Object} `context` | ||
* @param {Object} `app` The application instance | ||
* @param {Object} `view` The view being rendered | ||
* @param {Object} `context` The view's context | ||
* @param {Object} `options` | ||
*/ | ||
function Context(app, view, locals, context, helpers) { | ||
function Context(app, view, context, helpers) { | ||
this.helper = {}; | ||
@@ -161,5 +161,71 @@ this.helper.options = createHelperOptions(app, view, helpers); | ||
this.app = app; | ||
this.ctx = function() { | ||
return helperContext.apply(this, arguments); | ||
}; | ||
} | ||
/** | ||
* Expose `this.ctx()` in helpers for creating a custom context object | ||
* from a `view` being rendered, `locals` and helper `options` (which | ||
* can optionally have a handlebars `options.hash` property) | ||
* | ||
* The context object is created from: | ||
* | ||
* - `this.context`: the context for the **current view being rendered** | ||
* - `this.view.locals`: the `locals` object for current view being rendered | ||
* - `this.view.data`: front-matter from current view being rendered | ||
* - `view.locals`: locals defined on the view being injected | ||
* - `view.data`: front-matter on the view being injected | ||
* - helper `locals`: locals passed to the helper | ||
* - helper `options`: options passed to the helper | ||
* - helper `options.hash` if helper is registered as a handlebars helper | ||
* | ||
* Also note that `view` is the view being injected, whereas `this.view` | ||
* is the `view` being rendered. | ||
* | ||
* ```js | ||
* // handlebars helper | ||
* app.helper('foo', function(name, locals, options) { | ||
* var view = this.app.find(name); | ||
* var ctx = this.ctx(view, locals, options); | ||
* return options.fn(ctx); | ||
* }); | ||
* | ||
* // async helper | ||
* app.helper('foo', function(name, locals, options, cb) { | ||
* var view = this.app.find(name); | ||
* var ctx = this.ctx(view, locals, options); | ||
* view.render(ctx, function(err, res) { | ||
* if (err) return cb(err); | ||
* cb(null, res.content); | ||
* }); | ||
* }); | ||
* ``` | ||
* @name .this.ctx | ||
* @param {Object} `view` the view being injected | ||
* @param {Object} `locals` Helper locals | ||
* @param {Object} `options` Helper options | ||
* @return {Object} | ||
* @public | ||
*/ | ||
function helperContext(view, locals, options) { | ||
var fn = this.options.helperContext; | ||
var merge = utils.merge; | ||
var context = {}; | ||
if (typeof fn === 'function') { | ||
context = fn.call(this, view, locals, options); | ||
} else { | ||
// merge "view" front-matter with context | ||
context = merge({}, this.context, this.view.data); | ||
// merge in partial locals and front-matter | ||
context = merge({}, context, view.locals, view.data); | ||
// merge in helper locals and options.hash | ||
context = merge({}, context, locals, options.hash); | ||
} | ||
return context; | ||
} | ||
/** | ||
* Decorate the given object with `merge`, `set` and `get` methods | ||
@@ -219,3 +285,5 @@ */ | ||
var opts = options.helper; | ||
if (!utils.isObject(opts)) return helperOptions; | ||
if (!utils.isObject(opts)) { | ||
return helperOptions; | ||
} | ||
@@ -242,4 +310,2 @@ for (var key in opts) { | ||
app.define('mergePartials', mergePartials); | ||
function mergePartials(options) { | ||
@@ -324,32 +390,10 @@ var opts = utils.merge({}, this.options, options); | ||
}); | ||
}; | ||
// async.reduce(names, partials, function(acc, name, cb) { | ||
// var collection = self.views[name]; | ||
// async.eachOf(collection, function(view, key, next) { | ||
// // handle `onMerge` middleware | ||
// self.handleOnce('onMerge', view, function(err, file) { | ||
// if (err) return next(err); | ||
/** | ||
* Expose `mergePartials` functions as methods | ||
*/ | ||
// if (file.options.nomerge) { | ||
// return next(); | ||
// } | ||
// if (opts.mergePartials !== false) { | ||
// name = 'partials'; | ||
// } | ||
// // convert the partial to: | ||
// //=> {'foo.hbs': 'some content...'}; | ||
// acc[name] = acc[name] || {}; | ||
// acc[name][key] = file.content; | ||
// next(null, acc); | ||
// }); | ||
// }, function(err) { | ||
// if (err) return cb(err); | ||
// cb(null, partials); | ||
// }); | ||
// }, done); | ||
}; | ||
app.define('mergePartials', mergePartials); | ||
app.define('mergePartialsAsync', mergePartials.async); | ||
}; |
@@ -52,10 +52,19 @@ 'use strict'; | ||
/** | ||
* Register an engine for `ext` with the given `settings` | ||
* Register engine `ext` with the given render `fn` and/or `settings`. | ||
* | ||
* @param {String} `ext` The engine to get. | ||
* ```js | ||
* app.setEngine('hbs', require('engine-handlebars'), { | ||
* delims: ['<%', '%>'] | ||
* }); | ||
* ``` | ||
* @param {String} `ext` The engine to set. | ||
*/ | ||
proto.setEngine = function(ext, fn, settings) { | ||
debug('registering engine "%s"', ext); | ||
ext = utils.formatExt(ext); | ||
debug('registering engine "%s"', ext); | ||
settings = settings || {}; | ||
if (settings.default === true) { | ||
this._.engines.defaultEngine = ext; | ||
} | ||
this._.engines.setEngine(ext, fn, settings); | ||
@@ -66,5 +75,10 @@ return this; | ||
/** | ||
* Get the engine settings registered for the given `ext`. | ||
* Get registered engine `ext`. | ||
* | ||
* ```js | ||
* app.engine('hbs', require('engine-handlebars')); | ||
* var engine = app.getEngine('hbs'); | ||
* ``` | ||
* @param {String} `ext` The engine to get. | ||
* @api public | ||
*/ | ||
@@ -75,3 +89,3 @@ | ||
if (typeof ext !== 'string') { | ||
if (!utils.isString(ext)) { | ||
ext = this.option('view engine') | ||
@@ -82,3 +96,3 @@ || this.option('viewEngine') | ||
if (typeof ext === 'string') { | ||
if (utils.isString(ext)) { | ||
ext = utils.formatExt(ext); | ||
@@ -85,0 +99,0 @@ return this._.engines.getEngine(ext); |
@@ -137,3 +137,3 @@ 'use strict'; | ||
// Bind context to helpers before passing to the engine. | ||
this.bindHelpers(view, locals, ctx, (ctx.async = !!isAsync)); | ||
this.bindHelpers(view, ctx, (ctx.async = !!isAsync)); | ||
@@ -217,3 +217,3 @@ // shallow clone the context and locals | ||
// Bind context to helpers before passing to the engine. | ||
app.bindHelpers(view, locals, ctx, (ctx.async = !!isAsync)); | ||
app.bindHelpers(view, ctx, (ctx.async = !!isAsync)); | ||
@@ -314,2 +314,3 @@ app.mergePartialsAsync(engineOpts, function(err, partials) { | ||
view.content = res; | ||
delete view._context; | ||
@@ -316,0 +317,0 @@ // handle `postRender` middleware |
@@ -60,4 +60,5 @@ 'use strict'; | ||
utils.define(view, 'addView', views.addView.bind(views)); | ||
// pass the engine defined on `collection.options` to `view.options` | ||
view.engine = views.options.engine || view.engine; | ||
if (!view.engine) view.engine = views.options.engine; | ||
app.extendView(view, options); | ||
@@ -64,0 +65,0 @@ }); |
@@ -240,2 +240,10 @@ 'use strict'; | ||
/** | ||
* Return true if the given value is a string. | ||
*/ | ||
utils.isString = function(val) { | ||
return val && typeof val === 'string'; | ||
}; | ||
/** | ||
* Return true if the given value is a stream. | ||
@@ -242,0 +250,0 @@ */ |
@@ -57,2 +57,8 @@ 'use strict'; | ||
View.prototype.context = function(locals) { | ||
if (this._context) return this._context; | ||
if (typeof locals === 'function') { | ||
return locals.call(this, this); | ||
} | ||
if (arguments.length > 1) { | ||
@@ -63,3 +69,5 @@ locals = [].concat.apply([], [].slice.call(arguments)); | ||
} | ||
locals.unshift(utils.merge({}, this.locals, this.data)); | ||
locals.unshift(this.locals); | ||
locals.push(this.data); | ||
return utils.merge.apply(utils.merge, locals); | ||
@@ -117,2 +125,3 @@ }; | ||
this.contents = new Buffer(res); | ||
delete this._context; | ||
cb(null, this); | ||
@@ -230,5 +239,3 @@ }.bind(this)); | ||
} | ||
if (engine) { | ||
return engine; | ||
} | ||
return engine; | ||
} |
{ | ||
"name": "templates", | ||
"description": "System for creating and managing template collections, and rendering templates with any node.js template engine. Can be used as the basis for creating a static site generator or blog framework.", | ||
"version": "0.19.0", | ||
"version": "0.20.0", | ||
"homepage": "https://github.com/jonschlinkert/templates", | ||
@@ -77,2 +77,3 @@ "author": "Jon Schlinkert (https://github.com/jonschlinkert)", | ||
"resolve-glob": "^0.1.8", | ||
"rimraf": "^2.5.2", | ||
"should": "^8.3.1", | ||
@@ -79,0 +80,0 @@ "swig": "^1.4.2" |
@@ -210,5 +210,5 @@ # templates [![NPM version](https://img.shields.io/npm/v/templates.svg?style=flat)](https://www.npmjs.com/package/templates) [![NPM downloads](https://img.shields.io/npm/dm/templates.svg?style=flat)](https://npmjs.org/package/templates) [![Build Status](https://img.shields.io/travis/jonschlinkert/templates.svg?style=flat)](https://travis-ci.org/jonschlinkert/templates) | ||
### [.setup](index.js#L386) | ||
### [.setup](index.js#L374) | ||
Expose static `setup` method for providing access to an instance before any other use code is run. | ||
Expose static `setup` method for providing access to an instance before any other code is run. | ||
@@ -257,2 +257,17 @@ **Params** | ||
### [.getEngine](lib/plugins/engine.js#L84) | ||
Get registered engine `ext`. | ||
**Params** | ||
* `ext` **{String}**: The engine to get. | ||
**Example** | ||
```js | ||
app.engine('hbs', require('engine-handlebars')); | ||
var engine = app.getEngine('hbs'); | ||
``` | ||
*** | ||
@@ -456,3 +471,3 @@ | ||
### [.compile](lib/view.js#L81) | ||
### [.compile](lib/view.js#L89) | ||
@@ -475,3 +490,3 @@ Synchronously compile a view. | ||
### [.render](lib/view.js#L99) | ||
### [.render](lib/view.js#L107) | ||
@@ -493,3 +508,3 @@ Asynchronously render a view. | ||
### [.isType](lib/view.js#L133) | ||
### [.isType](lib/view.js#L142) | ||
@@ -547,3 +562,3 @@ Return true if the view is the given view `type`. Since types are assigned by collections, views that are "collection-less" will not have a type, and thus will always return `false` (as expected). | ||
### [.mergePartials](lib/plugins/context.js#L237) | ||
### [.mergePartials](lib/plugins/context.js#L305) | ||
@@ -559,3 +574,3 @@ Merge "partials" view types. This is necessary for template | ||
### [.mergePartialsAsync](lib/plugins/context.js#L277) | ||
### [.mergePartialsAsync](lib/plugins/context.js#L343) | ||
@@ -647,3 +662,3 @@ Merge "partials" view types. This is necessary for template engines | ||
### [.mergePartials](lib/plugins/context.js#L237) | ||
### [.mergePartials](lib/plugins/context.js#L305) | ||
@@ -659,3 +674,3 @@ Merge "partials" view types. This is necessary for template | ||
### [.mergePartialsAsync](lib/plugins/context.js#L277) | ||
### [.mergePartialsAsync](lib/plugins/context.js#L343) | ||
@@ -879,3 +894,3 @@ Merge "partials" view types. This is necessary for template engines | ||
### [.mergePartials](lib/plugins/context.js#L237) | ||
### [.mergePartials](lib/plugins/context.js#L305) | ||
@@ -891,3 +906,3 @@ Merge "partials" view types. This is necessary for template | ||
### [.mergePartialsAsync](lib/plugins/context.js#L277) | ||
### [.mergePartialsAsync](lib/plugins/context.js#L343) | ||
@@ -1125,3 +1140,3 @@ Merge "partials" view types. This is necessary for template engines | ||
### [.mergePartials](lib/plugins/context.js#L237) | ||
### [.mergePartials](lib/plugins/context.js#L305) | ||
@@ -1137,3 +1152,3 @@ Merge "partials" view types. This is necessary for template | ||
### [.mergePartialsAsync](lib/plugins/context.js#L277) | ||
### [.mergePartialsAsync](lib/plugins/context.js#L343) | ||
@@ -1410,3 +1425,3 @@ Merge "partials" view types. This is necessary for template engines | ||
### [.mergePartials](lib/plugins/context.js#L237) | ||
### [.mergePartials](lib/plugins/context.js#L305) | ||
@@ -1422,3 +1437,3 @@ Merge "partials" view types. This is necessary for template | ||
### [.mergePartialsAsync](lib/plugins/context.js#L277) | ||
### [.mergePartialsAsync](lib/plugins/context.js#L343) | ||
@@ -1624,3 +1639,3 @@ Merge "partials" view types. This is necessary for template engines | ||
### [.mergePartials](lib/plugins/context.js#L237) | ||
### [.mergePartials](lib/plugins/context.js#L305) | ||
@@ -1636,3 +1651,3 @@ Merge "partials" view types. This is necessary for template | ||
### [.mergePartialsAsync](lib/plugins/context.js#L277) | ||
### [.mergePartialsAsync](lib/plugins/context.js#L343) | ||
@@ -1919,2 +1934,25 @@ Merge "partials" view types. This is necessary for template engines | ||
### v0.20.0 | ||
**Context** | ||
* In general, context should be merged so that the most specific context wins over less specific. This fixes one case where locals was winning over front-matter | ||
**Helpers** | ||
* Exposes `.ctx()` method on helper context, to simplify merging context in non-built-in helpers | ||
**Engines** | ||
* Fixes bug that was using default engine on options instead of engine that matches view file extension. | ||
### v0.19.0 | ||
* Numerous [dependency updates](https://github.com/jonschlinkert/templates/commit/6f78d88aa1920b84d20177bf35942e596b8e58b5) | ||
### v0.18.0 | ||
* [Fixes inheritance bug](https://github.com/jonschlinkert/templates/commit/66b0d885648600c97b4a158eaebf3e95443ec66e) that only manifests in node v0.4.0 | ||
* Improved [error handling in routes](https://github.com/jonschlinkert/templates/commit/d7654b74502465587da1e490c09e486fbf43f6db) | ||
### v0.17.0 | ||
@@ -1929,2 +1967,3 @@ | ||
* Improved context handling | ||
* Ensure collection middleware is handled [after app middleware](https://github.com/jonschlinkert/templates/commit/f47385f5172a2773c3ab2a969ebfccc533ec5e27) | ||
@@ -2057,2 +2096,2 @@ ### v0.15.0 | ||
_This file was generated by [verb](https://github.com/verbose/verb), v0.9.0, on May 24, 2016._ | ||
_This file was generated by [verb](https://github.com/verbose/verb), v0.9.0, on May 26, 2016._ |
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
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
179031
4149
2077
21