Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

templates

Package Overview
Dependencies
Maintainers
3
Versions
154
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

templates - npm Package Compare versions

Comparing version 0.20.2 to 0.21.0

16

changelog.md

@@ -1,14 +0,16 @@

### v0.20.0
### v0.21.0
**Context**
**Breaking changes**
- 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
- The `queue` property has been removed, as well as related code for loading views using events. This behavior can easily be added using plugins or existing emitters.
**Helpers**
**Non-breaking**
- Exposes `.ctx()` method on helper context, to simplify merging context in non-built-in helpers
- The `View` and `Item` class have been externalized to modules [vinyl-item][] and [vinyl-view][] so they can be used in other libraries.
**Engines**
### v0.20.0
- Fixes bug that was using default engine on options instead of engine that matches view file extension.
- **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.

@@ -15,0 +17,0 @@ ### v0.19.0

@@ -18,18 +18,8 @@ /*!

/**
* Collection constructors
* Expose `Templates`
*/
var Collection = lib.collection;
var Views = lib.views;
var Group = lib.group;
var List = lib.list;
module.exports = exports = Templates;
/**
* Item constructors
*/
var Item = lib.item;
var View = lib.view;
/**
* This function is the main export of the templates module.

@@ -72,3 +62,3 @@ * Initialize an instance of `templates` to create your

debug('initializing <%s>, called from <%s>', __filename, module.parent.id);
Templates.emit('preInit', this);
Templates.emit('templates.preInit', this);

@@ -108,3 +98,3 @@ this.items = {};

Templates.setup(this, 'Templates');
Templates.emit('init', this);
Templates.emit('templates.postInit', this);
};

@@ -121,7 +111,4 @@

enumerable: true,
set: function(val) {
this.define(this, name, val);
},
get: function() {
return this.options[name] || lib[name.toLowerCase()];
return this.options[name] || Templates[name];
}

@@ -179,3 +166,3 @@ });

if (opts.isList === true) {
if (opts.isList === true || opts instanceof List) {
list = opts;

@@ -353,4 +340,4 @@ } else {

if (view.options && view.options.collection) {
var views = this[view.options.collection];
var layout = views.resolveLayout(view);
var collection = this[view.options.collection];
var layout = collection.resolveLayout(view);
if (typeof layout === 'undefined') {

@@ -394,8 +381,8 @@ layout = this.option('layout');

Templates.Base = Base;
Templates.Item = Item;
Templates.View = View;
Templates.List = List;
Templates.Collection = Collection;
Templates.Views = Views;
Templates.Group = Group;
Templates.Collection = lib.collection;
Templates.List = lib.list;
Templates.Group = lib.group;
Templates.Views = lib.views;
Templates.Item = require('vinyl-item');
Templates.View = require('vinyl-view');

@@ -408,7 +395,1 @@ /**

utils.define(Templates, '_', { lib: lib, plugin: plugin });
/**
* Expose `Templates`
*/
module.exports = Templates;

@@ -12,3 +12,3 @@ 'use strict';

module.exports = Collection;
module.exports = exports = Collection;

@@ -33,2 +33,4 @@ /**

this.is('Collection');
this.items = {};
this.use(utils.option());

@@ -58,12 +60,9 @@ this.use(utils.plugin());

this.define('List', opts.List || require('./list'));
this.define('Item', opts.Item || require('./item'));
this.define('loaded', false);
// add constructors to the instance
this.define('Item', opts.Item || Collection.Item);
this.define('View', opts.View || Collection.View);
this.use(plugin.renameKey());
this.use(plugin.item('item', 'Item'));
this.use(plugin.item('item', 'Item', {emit: false}));
this.queue = [];
this.items = {};
// if an instance of `List` or `Collection` is passed, load it now

@@ -84,12 +83,10 @@ if (Array.isArray(opts) || opts.isList) {

/**
* Set an item on the collection. This is identical to [addItem](#addItem)
* except `setItem` does not emit an event for each item and does not
* iterate over the item `queue`.
* Add an item to the collection.
*
* ```js
* collection.setItem('foo', {content: 'bar'});
* collection.addItem('foo', {content: 'bar'});
* ```
*
* @param {String|Object} `key` Item key or object
* @param {Object} `value` If key is a string, value is the item object.
* @emits `item` With the created `item` and `collection` instance as arguments.
* @param {String|Object} `key` Item name or object
* @param {Object} `val` Item object, when `key` is a string.
* @developer The `item` method is decorated onto the collection using the `item` plugin

@@ -100,8 +97,9 @@ * @return {Object} returns the `item` instance.

Collection.prototype.setItem = function(key, value) {
debug('setting item "%s"');
var item = this.item(key, value);
Collection.prototype.addItem = function(key, val) {
debug('adding item "%s"');
var item = this.item(key, val);
if (typeof item.use === 'function') {
this.run(item);
}
this.emit('item', item, this);
this.items[item.key] = item;

@@ -112,31 +110,18 @@ return item;

/**
* Similar to `setItem`, adds an item to the collection but also fires an
* event and iterates over the item `queue` to load items from the
* `addItem` event listener. An item may be an instance of `Item`, if
* not, the item is converted to an instance of `Item`.
* Get an item from `collection.items`.
*
* ```js
* var list = new List(...);
* list.addItem('a.html', {path: 'a.html', contents: '...'});
* collection.getItem('a.html');
* ```
* @param {String} `key`
* @param {Object} `value`
* @param {String} `key` Key of the item to get.
* @return {Object}
* @api public
*/
Collection.prototype.addItem = function(/*key, value*/) {
debug('adding item "%s"');
var args = [].slice.call(arguments);
this.emit.call(this, 'addItem', args);
var item = this.setItem.apply(this, args);
while (this.queue.length) {
this.setItem(this.queue.shift());
}
return item;
Collection.prototype.getItem = function(key) {
return this.items[key] || this.items[this.renameKey(key)];
};
/**
* Delete an item from collection `items`.
* Remove an item from `collection.items`.
*

@@ -178,5 +163,2 @@ * ```js

}
this.emit('addItems', items);
if (this.loaded) return this;
this.visit('addItem', items);

@@ -203,5 +185,2 @@ return this;

Collection.prototype.addList = function(list, fn) {
this.emit('addList', list);
if (this.loaded) return this;
if (!Array.isArray(list)) {

@@ -214,7 +193,7 @@ throw new TypeError('expected list to be an array.');

}
var len = list.length;
var idx = -1;
var len = list.length, i = -1;
while (++i < len) {
var item = fn(list[i]);
this.addItem(item.path, item);
while (++idx < len) {
this.addItem(fn(list[idx]));
}

@@ -225,14 +204,15 @@ return this;

/**
* Get an item from the collection.
*
* ```js
* collection.getItem('a.html');
* ```
* @param {String} `key` Key of the item to get.
* @return {Object}
* @api public
* Deprecated
*/
Collection.prototype.getItem = function(key) {
return this.items[key] || this.items[this.renameKey(key)];
Collection.prototype.setItem = function(/*key, value*/) {
console.log('`.setItem` is deprecated. Use `.addItem` instead.');
return this.addItem.apply(this, arguments);
};
/**
* Expose static properties
*/
utils.define(Collection, 'Item', require('vinyl-item'));
utils.define(Collection, 'View', require('vinyl-view'));

@@ -11,3 +11,3 @@ 'use strict';

module.exports = Group;
module.exports = exports = Group;

@@ -14,0 +14,0 @@ /**

@@ -6,6 +6,4 @@ 'use strict';

var plugin = require('./plugins');
var Group = require('./group');
var utils = require('./utils');
var Group = require('./group');
var Item = require('./item');
var View = require('./view');

@@ -16,3 +14,3 @@ /**

module.exports = List;
module.exports = exports = List;

@@ -60,2 +58,6 @@ /**

// add constructors to the instance
this.define('Item', opts.Item || List.Item);
this.define('View', opts.View || List.View);
// decorate the instance

@@ -66,8 +68,4 @@ this.use(plugin.init);

this.use(plugin.helpers);
this.use(plugin.item('item', 'Item'));
this.use(plugin.item('item', 'Item', {emit: false}));
// add constructors to the instance
this.define('Item', opts.Item || View);
this.define('View', opts.View || Item);
// decorate `isItem` and `isView`, in case custom class is passed

@@ -479,1 +477,8 @@ plugin.is(this.Item);

};
/**
* Expose static properties
*/
utils.define(List, 'Item', require('vinyl-item'));
utils.define(List, 'View', require('vinyl-view'));
'use strict';
var debug = require('debug');
var View = require('vinyl-view');
var utils = require('../utils');

@@ -67,2 +68,5 @@

}
if (typeof view.context !== 'function') {
view.context = View.context;
}
return utils.merge({}, this.cache.data, view.context(locals));

@@ -69,0 +73,0 @@ });

@@ -6,13 +6,16 @@ 'use strict';

/**
* Decorate an `item` or `view` method onto an `app` or
* `collection` instance.
* Adds a method to `app` for creating an instance of `Item` using the given `methodName`.
*
* ```js
* // register the plugin, define the method name to use
* // and the constructor name to use when inspected
* app.use(item('view', 'View'));
* ```
* @param {String} `methodName`
* @param {String} `CtorName` the constructor name to show when the item is inspected.
* @return {Function}
* @api public
*/
module.exports = function(method, CtorName) {
module.exports = function(methodName, CtorName, config) {
config = config || {};
return function(app) {

@@ -35,3 +38,3 @@

this.define(method, function(key, value) {
this.define(methodName, function(key, value) {
if (!value && typeof key === 'string') {

@@ -61,3 +64,3 @@ value = { path: key };

var Item = this.get(CtorName);
var item = !(value instanceof Item)
var item = (!value.isItem && !value.isView && !(value instanceof Item))
? new Item(value)

@@ -95,3 +98,5 @@ : value;

// emit the item, collection name, and collection instance (`app.on('view', ...)`)
this.emit(method, item, item.options.collection, this);
if (config.emit !== false && this.hasListeners(methodName)) {
this.emit(methodName, item, item.options.collection, this);
}

@@ -98,0 +103,0 @@ // if the instance is a top-level instance of templates (`isApp`), run plugins

@@ -9,26 +9,30 @@ 'use strict';

module.exports = function() {
module.exports = function(config) {
config = config || {};
return function(app) {
this.define('renameKey', renameKey);
function renameKey(key, file, fn) {
this.define('renameKey', function(key, file, fn) {
if (typeof key === 'function') {
fn = key;
key = null;
file = null;
return this.renameKey(null, null, key);
}
if (typeof file === 'function') {
fn = file;
file = null;
return this.renameKey(key, null, file);
}
if (typeof fn !== 'function') {
fn = app.option('renameKey') || utils.identity;
fn = this.options.renameKey;
}
app.options.renameKey = fn;
if (typeof fn !== 'function') {
fn = config.renameKey;
}
if (typeof fn !== 'function') {
fn = utils.identity;
}
this.options.renameKey = fn;
if (typeof key === 'string') {
return fn(key, file);
return fn.call(this, key, file);
}
return app;
}
return this;
});
};
};

@@ -16,3 +16,7 @@ 'use strict';

proto.viewType = proto.viewType || function(plural, types) {
if (typeof proto.viewType !== 'function') {
proto.viewType = viewType;
}
function viewType(plural, types) {
var len = types.length, i = 0;

@@ -27,3 +31,3 @@ while (len--) {

return types;
};
}

@@ -30,0 +34,0 @@ /**

@@ -9,19 +9,15 @@ 'use strict';

/**
* Plugins for [base](https://github.com/node-base/base)
* Lazily invoked module dependencies
*/
require('array-sort', 'sortBy');
require('async-each', 'each');
require('base-data');
require('base-option', 'option');
require('base-plugins', 'plugin');
/**
* Common utils
*/
require('array-sort', 'sortBy');
require('async-each', 'each');
require('clone');
require('clone-stats');
require('deep-bind', 'bindAll');
require('define-property', 'define');
require('en-route', 'router');
require('engine-base', 'engine');
require('engine-cache', 'Engines');
require('extend-shallow', 'extend');

@@ -34,2 +30,5 @@ require('falsey', 'isFalsey');

require('has-value', 'has');
require('inflection', 'inflect');
require('layouts');
require('load-helpers', 'loader');
require('match-file');

@@ -40,18 +39,2 @@ require('mixin-deep', 'merge');

require('set-value', 'set');
/**
* Middleware and routes
*/
require('en-route', 'router');
/**
* Engines, templates, helpers and related utils
*/
require('engine-base', 'engine');
require('engine-cache', 'Engines');
require('inflection', 'inflect');
require('layouts');
require('load-helpers', 'loader');
require('template-error', 'rethrow');

@@ -425,3 +408,3 @@ require = fn; // eslint-disable-line

/**
* Resolve the name of the engine to use, or the file
* Used on `collection` or `app` to resolve the name of the engine to use, or the file
* extension to use for the engine.

@@ -428,0 +411,0 @@ *

@@ -14,3 +14,3 @@ 'use strict';

module.exports = Views;
module.exports = exports = Views;

@@ -52,5 +52,13 @@ /**

/**
* Expose static properties
*/
Views.prototype.init = function(opts) {
debug('initializing');
// add constructors to the instance
this.define('Item', opts.Item || Views.Item);
this.define('View', opts.View || Views.View);
// decorate the instance

@@ -61,13 +69,6 @@ this.use(plugin.init);

this.use(plugin.helpers);
this.use(plugin.item('view', 'View'));
this.use(plugin.item('view', 'View', {emit: false}));
// setup listeners
this.listen(this);
// add constructors
this.define('List', opts.List || require('./list'));
this.define('View', opts.View || require('./view'));
this.define('loaded', false);
this.queue = [];
this.views = {};

@@ -97,3 +98,3 @@

this.on('use', function(fn) {
if (!fn) return;
if (typeof fn !== 'function') return;
for (var key in collection.views) {

@@ -125,3 +126,3 @@ if (collection.views.hasOwnProperty(key)) {

Views.prototype.setView = function(key, value) {
Views.prototype.addView = function(key, value) {
var view = this.view(key, value);

@@ -144,3 +145,5 @@ debug('adding view "%s"', view.path);

this.emit('load', view);
this.emit('view', view, this);
this.emit(name, view, this);
this.extendView(view);

@@ -153,28 +156,35 @@ // set the view on `collection.views`

/**
* Similar to [setView](#setView), adds a view to the collection
* but also fires an event and iterates over the loading `queue`
* for loading views from the `addView` event listener. If the
* given view is not already an instance of `View`, it will be
* converted to one before being added to the `views` object.
* Get view `name` from `collection.views`.
*
* ```js
* var views = new Views(...);
* views.addView('a.html', {path: 'a.html', contents: '...'});
* collection.getView('a.html');
* ```
* @param {String} `key`
* @param {Object} `value`
* @return {Object} Returns the instance of the created `View` to allow chaining view methods.
* @param {String} `key` Key of the view to get.
* @param {Function} `fn` Optionally pass a function to modify the key.
* @return {Object}
* @api public
*/
Views.prototype.addView = function(/*key, value*/) {
var args = [].slice.call(arguments);
this.emit.call(this, 'addView', args);
Views.prototype.getView = function(name, options, fn) {
if (typeof name !== 'string') {
throw new TypeError('expected a string');
}
var view = this.setView.apply(this, args);
while (this.queue.length) {
this.setView(this.queue.shift());
debug('getting view "%s"', name);
if (typeof options === 'function') {
fn = options;
options = {};
}
this.extendView(view);
return view;
var view = this.views[name] || this.views[this.renameKey(name)];
if (view) return view;
view = utils.getView(name, this.views, fn);
if (view) return view;
if (utils.fileExists(name)) {
return this.addView(name, {
contents: fs.readFileSync(name)
});
}
};

@@ -219,3 +229,2 @@

this.emit('addViews', views);
if (this.loaded) return this;
if (utils.hasGlob(views)) {

@@ -226,4 +235,3 @@ var name = '"' + this.options.plural + '"';

if (Array.isArray(views)) {
this.addList.apply(this, arguments);
return this;
return this.addList.apply(this, arguments);
}

@@ -255,3 +263,3 @@ if (arguments.length > 1 && utils.isView(view)) {

this.emit('addList', list);
if (this.loaded) return this;
if (utils.hasGlob(list)) {

@@ -261,2 +269,3 @@ var name = '"' + this.options.plural + '"';

}
if (!Array.isArray(list)) {

@@ -272,4 +281,3 @@ throw new TypeError('expected list to be an array.');

while (++idx < len) {
var view = fn(list[idx]);
this.addView(view.path, view);
this.addView(fn(list[idx]));
}

@@ -299,38 +307,2 @@ return this;

/**
* Get view `name` from `collection.views`.
*
* ```js
* collection.getView('a.html');
* ```
* @param {String} `key` Key of the view to get.
* @param {Function} `fn` Optionally pass a function to modify the key.
* @return {Object}
* @api public
*/
Views.prototype.getView = function(name, options, fn) {
if (typeof name !== 'string') {
throw new TypeError('expected a string');
}
debug('getting view "%s"', name);
if (typeof options === 'function') {
fn = options;
options = {};
}
var view = this.views[name] || this.views[this.renameKey(name)];
if (view) return view;
view = utils.getView(name, this.views, fn);
if (view) return view;
if (utils.fileExists(name)) {
return this.addView(name, {
contents: fs.readFileSync(name)
});
}
};
/**
* Load a view from the file system.

@@ -445,1 +417,17 @@ *

};
/**
* Deprecated
*/
Views.prototype.setView = function(/*key, value*/) {
console.log('`.setView` is deprecated. Use `.addView` instead.');
return this.addView.apply(this, arguments);
};
/**
* Expose static properties
*/
utils.define(Views, 'Item', require('vinyl-item'));
utils.define(Views, 'View', require('vinyl-view'));
{
"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.20.2",
"version": "0.21.0",
"homepage": "https://github.com/jonschlinkert/templates",

@@ -29,5 +29,3 @@ "author": "Jon Schlinkert (https://github.com/jonschlinkert)",

"base-option": "^0.8.2",
"base-plugins": "^0.4.12",
"clone": "^1.0.2",
"clone-stats": "^1.0.0",
"base-plugins": "^0.4.13",
"debug": "^2.2.0",

@@ -38,3 +36,3 @@ "deep-bind": "^0.3.0",

"engine-base": "^0.1.2",
"engine-cache": "^0.16.2",
"engine-cache": "^0.18.0",
"export-files": "^2.1.1",

@@ -58,7 +56,10 @@ "extend-shallow": "^2.0.1",

"template-error": "^0.1.2",
"vinyl": "^1.1.1"
"vinyl": "^1.1.1",
"vinyl-item": "^0.1.0",
"vinyl-view": "^0.1.0"
},
"devDependencies": {
"ansi-red": "^0.1.1",
"consolidate": "^0.14.0",
"base-test-runner": "^0.2.0",
"consolidate": "^0.14.1",
"engine-handlebars": "^0.8.0",

@@ -70,3 +71,3 @@ "ent": "^2.2.0",

"gulp-eslint": "^2.0.0",
"gulp-format-md": "^0.1.7",
"gulp-format-md": "^0.1.9",
"gulp-istanbul": "^0.10.4",

@@ -76,4 +77,3 @@ "gulp-mocha": "^2.2.0",

"is-buffer": "^1.1.3",
"kind-of": "^3.0.2",
"mocha": "^2.4.5",
"kind-of": "^3.0.3",
"parser-front-matter": "^1.3.0",

@@ -83,4 +83,5 @@ "remarkable": "^1.6.2",

"rimraf": "^2.5.2",
"should": "^8.3.1",
"swig": "^1.4.2"
"swig": "^1.4.2",
"verb-readme-generator": "^0.1.13",
"yargs-parser": "^2.4.0"
},

@@ -120,6 +121,8 @@ "keywords": [

"base",
"base-data",
"group-array",
"paginationator",
"base-data",
"verb"
"verb",
"vinyl-item",
"vinyl-view"
],

@@ -126,0 +129,0 @@ "lint": {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc