# 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) 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. ## Table of Contents - [Install](#install) - [Features](#features) - [Usage](#usage) * [Example](#example) - [API](#api) * [Common](#common) + [.option](#option) + [.use](#use) * [App](#app) * [Engines](#engines) * [Helpers](#helpers) * [Built-in helpers](#built-in-helpers) * [View](#view) + [View Data](#view-data) * [Item](#item) + [Item Data](#item-data) * [Views](#views) + [Views Data](#views-data) + [Lookup methods](#lookup-methods) * [Collections](#collections) * [List](#list) * [Group](#group) * [Lookups](#lookups) * [Rendering](#rendering) * [Context](#context) * [Middleware](#middleware) * [is](#is) - [More examples](#more-examples) - [History](#history) - [About](#about) * [Related projects](#related-projects) * [Contributing](#contributing) * [Building docs](#building-docs) * [Running tests](#running-tests) * [Author](#author) * [License](#license) _(TOC generated by [verb](https://github.com/verbose/verb) using [markdown-toc](https://github.com/jonschlinkert/markdown-toc))_ ## Install Install with [npm](https://www.npmjs.com/): ```sh $ npm install --save templates ``` ## Features * templates are [vinyl](http://github.com/gulpjs/vinyl) files * rich plugin support, use any [base](https://github.com/node-base/base) plugin! * render templates with any [template engine](#engine), including [nunjucks](https://github.com/jonschlinkert/engine-nunjucks), [handlebars](https://github.com/jonschlinkert/engine-handlebars), [lodash](https://github.com/jonschlinkert/engine-lodash) and any consolidate engine! * [helpers](#helpers): support for sync and async * [templates collections](#collections) support * partials and includes * layouts * pages * custom template "types" * pagination * [permalinks](https://github.com/assemble/assemble-permalinks) * [middleware](#middleware) can be used to tranform files at any stage in the render cycle * pagination * Much more! ## Usage ```js var templates = require('templates'); var app = templates(); ``` ### Example ```js // register an engine to automatically render `md` files app.engine('md', require('engine-lodash')); // create a template collection app.create('pages'); // add a template to the collection app.page('post.md', {content: 'This is the <%= title %> page'}); // render it app.render('post.md', {title: 'Home'}, function(err, view) { console.log(view.content); //=> 'This is the Home page' }); ``` ## API ### Common This section describes API features that are shared by all Templates classes. #### .option Set or get an option value. **Params** * `key` **{String|Object}**: Pass a key-value pair or an object to set. * `val` **{any}**: Any value when a key-value pair is passed. This can also be options if a glob pattern is passed as the first value. * `returns` **{Object}**: Returns the instance for chaining. **Example** ```js app.option('a', 'b'); app.option({c: 'd'}); console.log(app.options); //=> {a: 'b', c: 'd'} ``` #### .use Run a plugin on the given instance. Plugins are invoked immediately upon instantiating in the order in which they were defined. **Example** The simplest plugin looks something like the following: ```js app.use(function(inst) { // do something to `inst` }); ``` Note that `inst` is the instance of the class you're instantiating. So if you create an instance of `Collection`, inst is the collection instance. **Params** * `fn` **{Function}**: Plugin function. If the plugin returns a function it will be passed to the `use` method of each item created on the instance. * `returns` **{Object}**: Returns the instance for chaining. **Usage** ```js collection.use(function(items) { // `items` is the instance, as is `this` // optionally return a function to be passed to // the `.use` method of each item created on the // instance return function(item) { // do stuff to each `item` }; }); ``` ### App The `Templates` class is the main export of the `templates` library. All of the other classes are exposed as static properties on `Templates`: * [Item](#Item): Collection item, powered by [vinyl-item](https://github.com/jonschlinkert/vinyl-item). * [View](#View): Collection item, powered by [vinyl-view](https://github.com/jonschlinkert/vinyl-view). * [List](#List) * [Views](#Views): * [Collection](#Collection): Base collections class. Use this if you need to customize the render cycle, middleware stages, and so on. * [Group](#Group) ### [Templates](index.js#L36) This function is the main export of the templates module. Initialize an instance of `templates` to create your application. **Params** * `options` **{Object}** **Example** ```js var templates = require('templates'); var app = templates(); ``` ### [.list](index.js#L154) Create a new list. See the [list docs](docs/lists.md) for more information about lists. **Params** * `opts` **{Object}**: List options * `returns` **{Object}**: Returns the `list` instance for chaining. **Example** ```js var list = app.list(); list.addItem('abc', {content: '...'}); // or, create list from a collection app.create('pages'); var list = app.list(app.pages); ``` ### [.collection](index.js#L193) Create a new collection. Collections are decorated with special methods for getting and setting items from the collection. Note that, unlike the [create](#create) method, collections created with `.collection()` are not cached. See the [collection docs](docs/collections.md) for more information about collections. **Params** * `opts` **{Object}**: Collection options * `returns` **{Object}**: Returns the `collection` instance for chaining. ### [.create](index.js#L245) Create a new view collection to be stored on the `app.views` object. See the [create docs](docs/collections.md#create) for more details. **Params** * `name` **{String}**: The name of the collection to create. Plural or singular form may be used, as the inflections are automatically resolved when the collection is created. * `opts` **{Object}**: Collection options * `returns` **{Object}**: Returns the `collection` instance for chaining. ### [.setup](index.js#L375) Expose static `setup` method for providing access to an instance before any other code is run. **Params** * `app` **{Object}**: Application instance * `name` **{String}**: Optionally pass the constructor name to use. * `returns` **{undefined}** **Example** ```js function App(options) { Templates.call(this, options); Templates.setup(this); } Templates.extend(App); ``` *** ### [.engine](node_modules/base-engines/index.js#L45) Register a view engine callback `fn` as `ext`. Calls `.setEngine` and `.getEngine` internally. **Params** * `exts` **{String|Array}**: String or array of file extensions. * `fn` **{Function|Object}**: or `settings` * `settings` **{Object}**: Optionally pass engine options as the last argument. **Example** ```js app.engine('hbs', require('engine-handlebars')); // using consolidate.js var engine = require('consolidate'); app.engine('jade', engine.jade); app.engine('swig', engine.swig); // get a registered engine var swig = app.engine('swig'); ``` ### [.setEngine](node_modules/base-engines/index.js#L74) Register engine `ext` with the given render `fn` and/or `settings`. **Params** * `ext` **{String}**: The engine to set. **Example** ```js app.setEngine('hbs', require('engine-handlebars'), { delims: ['<%', '%>'] }); ``` ### [.getEngine](node_modules/base-engines/index.js#L97) Get registered engine `ext`. **Params** * `ext` **{String}**: The engine to get. **Example** ```js app.engine('hbs', require('engine-handlebars')); var engine = app.getEngine('hbs'); ``` *** ### [.helper](node_modules/base-helpers/index.js#L46) Register a template helper. **Params** * `name` **{String}**: Helper name * `fn` **{Function}**: Helper function. **Example** ```js app.helper('upper', function(str) { return str.toUpperCase(); }); ``` ### [.helpers](node_modules/base-helpers/index.js#L67) Register multiple template helpers. **Params** * `helpers` **{Object|Array}**: Object, array of objects, or glob patterns. **Example** ```js app.helpers({ foo: function() {}, bar: function() {}, baz: function() {} }); ``` ### [.asyncHelper](node_modules/base-helpers/index.js#L86) Register an async helper. **Params** * `name` **{String}**: Helper name. * `fn` **{Function}**: Helper function **Example** ```js app.asyncHelper('upper', function(str, next) { next(null, str.toUpperCase()); }); ``` ### [.asyncHelpers](node_modules/base-helpers/index.js#L107) Register multiple async template helpers. **Params** * `helpers` **{Object|Array}**: Object, array of objects, or glob patterns. **Example** ```js app.asyncHelpers({ foo: function() {}, bar: function() {}, baz: function() {} }); ``` ### [.getHelper](node_modules/base-helpers/index.js#L124) Get a previously registered helper. **Params** * `name` **{String}**: Helper name * `returns` **{Function}**: Returns the registered helper function. **Example** ```js var fn = app.getHelper('foo'); ``` ### [.getAsyncHelper](node_modules/base-helpers/index.js#L141) Get a previously registered async helper. **Params** * `name` **{String}**: Helper name * `returns` **{Function}**: Returns the registered helper function. **Example** ```js var fn = app.getAsyncHelper('foo'); ``` ### [.hasHelper](node_modules/base-helpers/index.js#L160) Return true if sync helper `name` is registered. **Params** * `name` **{String}**: sync helper name * `returns` **{Boolean}**: Returns true if the sync helper is registered **Example** ```js if (app.hasHelper('foo')) { // do stuff } ``` ### [.hasAsyncHelper](node_modules/base-helpers/index.js#L178) Return true if async helper `name` is registered. **Params** * `name` **{String}**: Async helper name * `returns` **{Boolean}**: Returns true if the async helper is registered **Example** ```js if (app.hasAsyncHelper('foo')) { // do stuff } ``` ### [.helperGroup](node_modules/base-helpers/index.js#L201) Register a namespaced helper group. **Params** * `helpers` **{Object|Array}**: Object, array of objects, or glob patterns. **Example** ```js // markdown-utils app.helperGroup('mdu', { foo: function() {}, bar: function() {}, }); // Usage: // <%= mdu.foo() %> // <%= mdu.bar() %> ``` ### Built-in helpers *** ### View API for the `View` class. ### [View](node_modules/vinyl-view/index.js#L26) Create an instance of `View`. Optionally pass a default object to use. **Params** * `view` **{Object}** **Example** ```js var view = new View({ path: 'foo.html', contents: new Buffer('...') }); ``` ### [.compile](node_modules/vinyl-view/index.js#L57) Synchronously compile a view. **Params** * `locals` **{Object}**: Optionally pass locals to the engine. * `returns` **{Object}** `View`: instance, for chaining. **Example** ```js var view = page.compile(); view.fn({title: 'A'}); view.fn({title: 'B'}); view.fn({title: 'C'}); ``` ### [.renderSync](node_modules/vinyl-view/index.js#L75) Synchronously render templates in `view.content`. **Params** * `locals` **{Object}**: Optionally pass locals to the engine. * `returns` **{Object}** `View`: instance, for chaining. **Example** ```js var view = new View({content: 'This is <%= title %>'}); view.renderSync({title: 'Home'}); console.log(view.content); ``` ### [.render](node_modules/vinyl-view/index.js#L101) Asynchronously render templates in `view.content`. **Params** * `locals` **{Object}**: Context to use for rendering templates. **Example** ```js view.render({title: 'Home'}, function(err, res) { //=> view object with rendered `content` }); ``` ### [.context](node_modules/vinyl-view/index.js#L132) Create a context object from `locals` and the `view.data` and `view.locals` objects. The `view.data` property is typically created from front-matter, and `view.locals` is used when a `new View()` is created. This method be overridden either by defining a custom `view.options.context` function to customize context for a view instance, or static [View.context](#view-context) function to customize context for all view instances. **Params** * `locals` **{Object}**: Optionally pass a locals object to merge onto the context. * `returns` **{Object}**: Returns the context object. **Example** ```js var page = new View({path: 'a/b/c.txt', locals: {a: 'b', c: 'd'}}); var ctx = page.context({a: 'z'}); console.log(ctx); //=> {a: 'z', c: 'd'} ``` ### [.isType](node_modules/vinyl-view/index.js#L148) Returns true if the view is the given `viewType`. Returns `false` if no type is assigned. When used with vinyl-collections, types are assigned by their respective collections. **Params** * `type` **{String}**: (`renderable`, `partial`, `layout`) **Example** ```js var view = new View({path: 'a/b/c.txt', viewType: 'partial'}) view.isType('partial'); ``` ### [.View.context](node_modules/vinyl-view/index.js#L248) Define a custom static `View.context` function to override default `.context` behavior. See the [context](#context) docs for more info. **Params** * `locals` **{Object}** * `returns` **{Object}** **Example** ```js // custom context function View.context = function(locals) { // `this` is the view being rendered return locals; }; ``` ### [.data](lib/plugins/context.js#L42) Set, get and load data to be passed to templates as context at render-time. **Params** * `key` **{String|Object}**: Pass a key-value pair or an object to set. * `val` **{any}**: Any value when a key-value pair is passed. This can also be options if a glob pattern is passed as the first value. * `returns` **{Object}**: Returns an instance of `Templates` for chaining. **Example** ```js app.data('a', 'b'); app.data({c: 'd'}); console.log(app.cache.data); //=> {a: 'b', c: 'd'} ``` ### [.context](lib/plugins/context.js#L62) Build the context for the given `view` and `locals`. **Params** * `view` **{Object}**: The view being rendered * `locals` **{Object}** * `returns` **{Object}**: The object to be passed to engines/views as context. ### [setHelperOptions](lib/plugins/context.js#L119) Update context in a helper so that `this.helper.options` is the options for that specific helper. **Params** * `context` **{Object}** * `key` **{String}** ### [.mergePartials](lib/plugins/context.js#L309) Merge "partials" view types. This is necessary for template engines have no support for partials or only support one type of partials. **Params** * `options` **{Object}**: Optionally pass an array of `viewTypes` to include on `options.viewTypes` * `returns` **{Object}**: Merged partials ### [.mergePartialsAsync](lib/plugins/context.js#L350) Merge "partials" view types. This is necessary for template engines have no support for partials or only support one type of partials. **Params** * `options` **{Object}**: Optionally pass an array of `viewTypes` to include on `options.viewTypes` * `callback` **{Function}**: Function that exposes `err` and `partials` parameters *** ### Item API for the `Item` class. ### [Item](node_modules/vinyl-item/index.js#L28) Create an instance of `Item`. Optionally pass a default object to use. See [vinyl](http://github.com/gulpjs/vinyl) docs for API details and additional documentation. **Params** * `item` **{Object}** **Example** ```js var item = new Item({ path: 'foo.html', contents: new Buffer('...') }); ``` ### [.content](node_modules/vinyl-item/index.js#L184) Normalize the `content` and `contents` properties on `item`. This is done to ensure compatibility with the vinyl convention of using `contents` as a Buffer, as well as the assemble convention of using `content` as a string. We will eventually deprecate the `content` property. **Example** ```js var item = new Item({path: 'foo/bar.hbs', contents: new Buffer('foo')}); console.log(item.content); //=> 'foo' ``` ### [.engine](node_modules/vinyl-item/index.js#L206) Getter/setter to resolve the name of the `engine` to use for rendering. **Example** ```js var item = new Item({path: 'foo/bar.hbs'}); console.log(item.engine); //=> '.hbs' ``` ### [.data](lib/plugins/context.js#L42) Set, get and load data to be passed to templates as context at render-time. **Params** * `key` **{String|Object}**: Pass a key-value pair or an object to set. * `val` **{any}**: Any value when a key-value pair is passed. This can also be options if a glob pattern is passed as the first value. * `returns` **{Object}**: Returns an instance of `Templates` for chaining. **Example** ```js app.data('a', 'b'); app.data({c: 'd'}); console.log(app.cache.data); //=> {a: 'b', c: 'd'} ``` ### [.context](lib/plugins/context.js#L62) Build the context for the given `view` and `locals`. **Params** * `view` **{Object}**: The view being rendered * `locals` **{Object}** * `returns` **{Object}**: The object to be passed to engines/views as context. ### [setHelperOptions](lib/plugins/context.js#L119) Update context in a helper so that `this.helper.options` is the options for that specific helper. **Params** * `context` **{Object}** * `key` **{String}** ### [.mergePartials](lib/plugins/context.js#L309) Merge "partials" view types. This is necessary for template engines have no support for partials or only support one type of partials. **Params** * `options` **{Object}**: Optionally pass an array of `viewTypes` to include on `options.viewTypes` * `returns` **{Object}**: Merged partials ### [.mergePartialsAsync](lib/plugins/context.js#L350) Merge "partials" view types. This is necessary for template engines have no support for partials or only support one type of partials. **Params** * `options` **{Object}**: Optionally pass an array of `viewTypes` to include on `options.viewTypes` * `callback` **{Function}**: Function that exposes `err` and `partials` parameters *** ### Views API for the `Views` class. ### [Views](lib/views.js#L28) Create an instance of `Views` with the given `options`. **Params** * `options` **{Object}** **Example** ```js var collection = new Views(); collection.addView('foo', {content: 'bar'}); ``` ### [.addView](lib/views.js#L126) Add a view to `collection.views`. This is identical to [addView](#addView) except `setView` returns the collection instance, and `addView` returns the item instance. **Params** * `key` **{String|Object}**: View key or object * `value` **{Object}**: If key is a string, value is the view object. * `returns` **{Object}**: returns the `view` instance. **Example** ```js collection.setView('foo', {content: 'bar'}); ``` ### [.setView](lib/views.js#L168) Set a view on the collection. This is identical to [addView](#addView) except `setView` does not emit an event for each view. **Params** * `key` **{String|Object}**: View key or object * `value` **{Object}**: If key is a string, value is the view object. * `returns` **{Object}**: returns the `view` instance. **Example** ```js collection.setView('foo', {content: 'bar'}); ``` ### [.getView](lib/views.js#L185) Get view `name` from `collection.views`. **Params** * `key` **{String}**: Key of the view to get. * `fn` **{Function}**: Optionally pass a function to modify the key. * `returns` **{Object}** **Example** ```js collection.getView('a.html'); ``` ### [.deleteView](lib/views.js#L220) Delete a view from collection `views`. **Params** * `key` **{String}** * `returns` **{Object}**: Returns the instance for chaining **Example** ```js views.deleteView('foo.html'); ``` ### [.addViews](lib/views.js#L244) Load multiple views onto the collection. **Params** * `views` **{Object|Array}** * `returns` **{Object}**: returns the `collection` object **Example** ```js collection.addViews({ 'a.html': {content: '...'}, 'b.html': {content: '...'}, 'c.html': {content: '...'} }); ``` ### [.addList](lib/views.js#L276) Load an array of views onto the collection. **Params** * `list` **{Array}** * `returns` **{Object}**: returns the `views` instance **Example** ```js collection.addList([ {path: 'a.html', content: '...'}, {path: 'b.html', content: '...'}, {path: 'c.html', content: '...'} ]); ``` ### [.groupBy](lib/views.js#L313) Group all collection `views` by the given property, properties or compare functions. See [group-array](https://github.com/doowb/group-array) for the full range of available features and options. * `returns` **{Object}**: Returns an object of grouped views. **Example** ```js var collection = new Collection(); collection.addViews(...); var groups = collection.groupBy('data.date', 'data.slug'); ``` ### [.isType](lib/views.js#L343) Return true if the collection belongs to the given view `type`. **Params** * `type` **{String}**: (`renderable`, `partial`, `layout`) **Example** ```js collection.isType('partial'); ``` ### [.viewTypes](lib/views.js#L390) Alias for `viewType` ### [.data](lib/plugins/context.js#L42) Set, get and load data to be passed to templates as context at render-time. **Params** * `key` **{String|Object}**: Pass a key-value pair or an object to set. * `val` **{any}**: Any value when a key-value pair is passed. This can also be options if a glob pattern is passed as the first value. * `returns` **{Object}**: Returns an instance of `Templates` for chaining. **Example** ```js app.data('a', 'b'); app.data({c: 'd'}); console.log(app.cache.data); //=> {a: 'b', c: 'd'} ``` ### [.context](lib/plugins/context.js#L62) Build the context for the given `view` and `locals`. **Params** * `view` **{Object}**: The view being rendered * `locals` **{Object}** * `returns` **{Object}**: The object to be passed to engines/views as context. ### [setHelperOptions](lib/plugins/context.js#L119) Update context in a helper so that `this.helper.options` is the options for that specific helper. **Params** * `context` **{Object}** * `key` **{String}** ### [.mergePartials](lib/plugins/context.js#L309) Merge "partials" view types. This is necessary for template engines have no support for partials or only support one type of partials. **Params** * `options` **{Object}**: Optionally pass an array of `viewTypes` to include on `options.viewTypes` * `returns` **{Object}**: Merged partials ### [.mergePartialsAsync](lib/plugins/context.js#L350) Merge "partials" view types. This is necessary for template engines have no support for partials or only support one type of partials. **Params** * `options` **{Object}**: Optionally pass an array of `viewTypes` to include on `options.viewTypes` * `callback` **{Function}**: Function that exposes `err` and `partials` parameters *** ### [.find](lib/plugins/lookup.js#L25) Find a view by `name`, optionally passing a `collection` to limit the search. If no collection is passed all `renderable` collections will be searched. **Params** * `name` **{String}**: The name/key of the view to find * `colleciton` **{String}**: Optionally pass a collection name (e.g. pages) * `returns` **{Object|undefined}**: Returns the view if found, or `undefined` if not. **Example** ```js var page = app.find('my-page.hbs'); // optionally pass a collection name as the second argument var page = app.find('my-page.hbs', 'pages'); ``` ### [.getView](lib/plugins/lookup.js#L64) Get view `key` from the specified `collection`. **Params** * `collection` **{String}**: Collection name, e.g. `pages` * `key` **{String}**: Template name * `fn` **{Function}**: Optionally pass a `renameKey` function * `returns` **{Object}** **Example** ```js var view = app.getView('pages', 'a/b/c.hbs'); // optionally pass a `renameKey` function to modify the lookup var view = app.getView('pages', 'a/b/c.hbs', function(fp) { return path.basename(fp); }); ``` ### [.getViews](lib/plugins/lookup.js#L103) Get all views from a `collection` using the collection's singular or plural name. **Params** * `name` **{String}**: The collection name, e.g. `pages` or `page` * `returns` **{Object}** **Example** ```js var pages = app.getViews('pages'); //=> { pages: {'home.hbs': { ... }} var posts = app.getViews('posts'); //=> { posts: {'2015-10-10.md': { ... }} ``` *** ### Collections API for the `Collections` class. ### [Collection](lib/collection.js#L25) Create an instance of `Collection` with the given `options`. **Params** * `options` **{Object}** **Example** ```js var collection = new Collection(); collection.addItem('foo', {content: 'bar'}); ``` ### [.addItem](lib/collection.js#L93) Add an item to the collection. **Params** * `key` **{String|Object}**: Item name or object * `val` **{Object}**: Item object, when `key` is a string. * `returns` **{Object}**: returns the `item` instance. **Events** * `emits`: `item` With the created `item` and `collection` instance as arguments. **Example** ```js collection.addItem('foo', {content: 'bar'}); ``` ### [.setItem](lib/collection.js#L118) Identical to `.addItem`, except the collection instance is returned instead of the item, to allow chaining. **Params** * `key` **{String|Object}**: Item name or object * `val` **{Object}**: Item object, when `key` is a string. * `returns` **{Object}**: returns the `collection` instance. **Events** * `emits`: `item` With the created `item` and `collection` instance as arguments. **Example** ```js collection.setItem('foo', {content: 'bar'}); ``` ### [.getItem](lib/collection.js#L134) Get an item from `collection.items`. **Params** * `key` **{String}**: Key of the item to get. * `returns` **{Object}** **Example** ```js collection.getItem('a.html'); ``` ### [.deleteItem](lib/collection.js#L149) Remove an item from `collection.items`. **Params** * `key` **{String}** * `returns` **{Object}**: Returns the instance for chaining **Example** ```js items.deleteItem('abc'); ``` ### [.addItems](lib/collection.js#L172) Load multiple items onto the collection. **Params** * `items` **{Object|Array}** * `returns` **{Object}**: returns the instance for chaining **Example** ```js collection.addItems({ 'a.html': {content: '...'}, 'b.html': {content: '...'}, 'c.html': {content: '...'} }); ``` ### [.addList](lib/collection.js#L196) Load an array of items onto the collection. **Params** * `items` **{Array}**: or an instance of `List` * `fn` **{Function}**: Optional sync callback function that is called on each item. * `returns` **{Object}**: returns the Collection instance for chaining **Example** ```js collection.addList([ {path: 'a.html', content: '...'}, {path: 'b.html', content: '...'}, {path: 'c.html', content: '...'} ]); ``` ### [.data](lib/plugins/context.js#L42) Set, get and load data to be passed to templates as context at render-time. **Params** * `key` **{String|Object}**: Pass a key-value pair or an object to set. * `val` **{any}**: Any value when a key-value pair is passed. This can also be options if a glob pattern is passed as the first value. * `returns` **{Object}**: Returns an instance of `Templates` for chaining. **Example** ```js app.data('a', 'b'); app.data({c: 'd'}); console.log(app.cache.data); //=> {a: 'b', c: 'd'} ``` ### [.context](lib/plugins/context.js#L62) Build the context for the given `view` and `locals`. **Params** * `view` **{Object}**: The view being rendered * `locals` **{Object}** * `returns` **{Object}**: The object to be passed to engines/views as context. ### [setHelperOptions](lib/plugins/context.js#L119) Update context in a helper so that `this.helper.options` is the options for that specific helper. **Params** * `context` **{Object}** * `key` **{String}** ### [.mergePartials](lib/plugins/context.js#L309) Merge "partials" view types. This is necessary for template engines have no support for partials or only support one type of partials. **Params** * `options` **{Object}**: Optionally pass an array of `viewTypes` to include on `options.viewTypes` * `returns` **{Object}**: Merged partials ### [.mergePartialsAsync](lib/plugins/context.js#L350) Merge "partials" view types. This is necessary for template engines have no support for partials or only support one type of partials. **Params** * `options` **{Object}**: Optionally pass an array of `viewTypes` to include on `options.viewTypes` * `callback` **{Function}**: Function that exposes `err` and `partials` parameters *** ### List API for the `List` class. ### [List](lib/list.js#L29) Create an instance of `List` with the given `options`. Lists differ from collections in that items are stored as an array, allowing items to be paginated, sorted, and grouped. **Params** * `options` **{Object}** **Example** ```js var list = new List(); list.addItem('foo', {content: 'bar'}); ``` ### [.addItem](lib/list.js#L108) Add an item to `list.items`. This is identical to [setItem](#setItem) except `addItem` returns the `item`, add `setItem` returns the instance of `List`. **Params** * `key` **{String|Object}**: Item key or object * `value` **{Object}**: If key is a string, value is the item object. * `returns` **{Object}**: returns the `item` instance. **Example** ```js collection.addItem('foo', {content: 'bar'}); ``` ### [.setItem](lib/list.js#L146) Add an item to `list.items`. This is identical to [addItem](#addItem) except `addItem` returns the `item`, add `setItem` returns the instance of `List`. **Params** * `key` **{String}** * `value` **{Object}** * `returns` **{Object}**: Returns the instance of `List` to support chaining. **Example** ```js var items = new Items(...); items.setItem('a.html', {path: 'a.html', contents: '...'}); ``` ### [.addItems](lib/list.js#L166) Load multiple items onto the collection. **Params** * `items` **{Object|Array}** * `returns` **{Object}**: returns the instance for chaining **Example** ```js collection.addItems({ 'a.html': {content: '...'}, 'b.html': {content: '...'}, 'c.html': {content: '...'} }); ``` ### [.addList](lib/list.js#L195) Load an array of items or the items from another instance of `List`. **Params** * `items` **{Array}**: or an instance of `List` * `fn` **{Function}**: Optional sync callback function that is called on each item. * `returns` **{Object}**: returns the List instance for chaining **Example** ```js var foo = new List(...); var bar = new List(...); bar.addList(foo); ``` ### [.hasItem](lib/list.js#L232) Return true if the list has the given item (name). **Params** * `key` **{String}** * `returns` **{Object}** **Example** ```js list.addItem('foo.html', {content: '...'}); list.hasItem('foo.html'); //=> true ``` ### [.getIndex](lib/list.js#L248) Get a the index of a specific item from the list by `key`. **Params** * `key` **{String}** * `returns` **{Object}** **Example** ```js list.getIndex('foo.html'); //=> 1 ``` ### [.getItem](lib/list.js#L292) Get a specific item from the list by `key`. **Params** * `key` **{String}**: The item name/key. * `returns` **{Object}** **Example** ```js list.getItem('foo.html'); //=> '>' ``` ### [.getView](lib/list.js#L311) Proxy for `getItem` **Params** * `key` **{String}**: Pass the key of the `item` to get. * `returns` **{Object}** **Example** ```js list.getItem('foo.html'); //=> '>' ``` ### [.deleteItem](lib/list.js#L325) Remove an item from the list. **Params** * `key` **{Object|String}**: Pass an `item` instance (object) or `item.key` (string). **Example** ```js list.deleteItem('a.html'); ``` ### [.extendItem](lib/list.js#L344) Decorate each item on the list with additional methods and properties. This provides a way of easily overriding defaults. **Params** * `item` **{Object}** * `returns` **{Object}**: Instance of item for chaining ### [.groupBy](lib/list.js#L363) Group all list `items` using the given property, properties or compare functions. See [group-array](https://github.com/doowb/group-array) for the full range of available features and options. * `returns` **{Object}**: Returns the grouped items. **Example** ```js var list = new List(); list.addItems(...); var groups = list.groupBy('data.date', 'data.slug'); ``` ### [.sortBy](lib/list.js#L389) Sort all list `items` using the given property, properties or compare functions. See [array-sort](https://github.com/jonschlinkert/array-sort) for the full range of available features and options. * `returns` **{Object}**: Returns a new `List` instance with sorted items. **Example** ```js var list = new List(); list.addItems(...); var result = list.sortBy('data.date'); //=> new sorted list ``` ### [.paginate](lib/list.js#L437) Paginate all `items` in the list with the given options, See [paginationator](https://github.com/doowb/paginationator) for the full range of available features and options. * `returns` **{Object}**: Returns the paginated items. **Example** ```js var list = new List(items); var pages = list.paginate({limit: 5}); ``` ### [.data](lib/plugins/context.js#L42) Set, get and load data to be passed to templates as context at render-time. **Params** * `key` **{String|Object}**: Pass a key-value pair or an object to set. * `val` **{any}**: Any value when a key-value pair is passed. This can also be options if a glob pattern is passed as the first value. * `returns` **{Object}**: Returns an instance of `Templates` for chaining. **Example** ```js app.data('a', 'b'); app.data({c: 'd'}); console.log(app.cache.data); //=> {a: 'b', c: 'd'} ``` ### [.context](lib/plugins/context.js#L62) Build the context for the given `view` and `locals`. **Params** * `view` **{Object}**: The view being rendered * `locals` **{Object}** * `returns` **{Object}**: The object to be passed to engines/views as context. ### [setHelperOptions](lib/plugins/context.js#L119) Update context in a helper so that `this.helper.options` is the options for that specific helper. **Params** * `context` **{Object}** * `key` **{String}** ### [.mergePartials](lib/plugins/context.js#L309) Merge "partials" view types. This is necessary for template engines have no support for partials or only support one type of partials. **Params** * `options` **{Object}**: Optionally pass an array of `viewTypes` to include on `options.viewTypes` * `returns` **{Object}**: Merged partials ### [.mergePartialsAsync](lib/plugins/context.js#L350) Merge "partials" view types. This is necessary for template engines have no support for partials or only support one type of partials. **Params** * `options` **{Object}**: Optionally pass an array of `viewTypes` to include on `options.viewTypes` * `callback` **{Function}**: Function that exposes `err` and `partials` parameters *** ### Group API for the `Group` class. ### [Group](lib/group.js#L25) Create an instance of `Group` with the given `options`. **Params** * `options` **{Object}** **Example** ```js var group = new Group({ 'foo': { items: [1,2,3] } }); ``` *** ### [.find](lib/plugins/lookup.js#L25) Find a view by `name`, optionally passing a `collection` to limit the search. If no collection is passed all `renderable` collections will be searched. **Params** * `name` **{String}**: The name/key of the view to find * `colleciton` **{String}**: Optionally pass a collection name (e.g. pages) * `returns` **{Object|undefined}**: Returns the view if found, or `undefined` if not. **Example** ```js var page = app.find('my-page.hbs'); // optionally pass a collection name as the second argument var page = app.find('my-page.hbs', 'pages'); ``` ### [.getView](lib/plugins/lookup.js#L64) Get view `key` from the specified `collection`. **Params** * `collection` **{String}**: Collection name, e.g. `pages` * `key` **{String}**: Template name * `fn` **{Function}**: Optionally pass a `renameKey` function * `returns` **{Object}** **Example** ```js var view = app.getView('pages', 'a/b/c.hbs'); // optionally pass a `renameKey` function to modify the lookup var view = app.getView('pages', 'a/b/c.hbs', function(fp) { return path.basename(fp); }); ``` ### [.getViews](lib/plugins/lookup.js#L103) Get all views from a `collection` using the collection's singular or plural name. **Params** * `name` **{String}**: The collection name, e.g. `pages` or `page` * `returns` **{Object}** **Example** ```js var pages = app.getViews('pages'); //=> { pages: {'home.hbs': { ... }} var posts = app.getViews('posts'); //=> { posts: {'2015-10-10.md': { ... }} ``` *** ### [.compile](lib/plugins/render.js#L98) Compile `content` with the given `locals`. **Params** * `view` **{Object|String}**: View object. * `locals` **{Object}** * `isAsync` **{Boolean}**: Load async helpers * `returns` **{Object}**: View object with compiled `view.fn` property. **Example** ```js var indexPage = app.page('some-index-page.hbs'); var view = app.compile(indexPage); // view.fn => [function] // you can call the compiled function more than once // to render the view with different data view.fn({title: 'Foo'}); view.fn({title: 'Bar'}); view.fn({title: 'Baz'}); ``` ### [.compileAsync](lib/plugins/render.js#L173) Asynchronously compile `content` with the given `locals` and callback. _(fwiw, this method name uses the unconventional "*Async" nomenclature to allow us to preserve the synchronous behavior of the `view.compile` method as well as the name)_. **Params** * `view` **{Object|String}**: View object. * `locals` **{Object}** * `isAsync` **{Boolean}**: Pass true to load helpers as async (mostly used internally) * `callback` **{Function}**: function that exposes `err` and the `view` object with compiled `view.fn` property **Example** ```js var indexPage = app.page('some-index-page.hbs'); app.compileAsync(indexPage, function(err, view) { // view.fn => compiled function }); ``` ### [.render](lib/plugins/render.js#L260) Render a view with the given `locals` and `callback`. **Params** * `view` **{Object|String}**: Instance of `View` * `locals` **{Object}**: Locals to pass to template engine. * `callback` **{Function}** **Example** ```js var blogPost = app.post.getView('2015-09-01-foo-bar'); app.render(blogPost, {title: 'Foo'}, function(err, view) { // `view` is an object with a rendered `content` property }); ``` *** ### [.data](lib/plugins/context.js#L42) Set, get and load data to be passed to templates as context at render-time. **Params** * `key` **{String|Object}**: Pass a key-value pair or an object to set. * `val` **{any}**: Any value when a key-value pair is passed. This can also be options if a glob pattern is passed as the first value. * `returns` **{Object}**: Returns an instance of `Templates` for chaining. **Example** ```js app.data('a', 'b'); app.data({c: 'd'}); console.log(app.cache.data); //=> {a: 'b', c: 'd'} ``` ### [.context](lib/plugins/context.js#L62) Build the context for the given `view` and `locals`. **Params** * `view` **{Object}**: The view being rendered * `locals` **{Object}** * `returns` **{Object}**: The object to be passed to engines/views as context. ### [setHelperOptions](lib/plugins/context.js#L119) Update context in a helper so that `this.helper.options` is the options for that specific helper. **Params** * `context` **{Object}** * `key` **{String}** ### [.mergePartials](lib/plugins/context.js#L309) Merge "partials" view types. This is necessary for template engines have no support for partials or only support one type of partials. **Params** * `options` **{Object}**: Optionally pass an array of `viewTypes` to include on `options.viewTypes` * `returns` **{Object}**: Merged partials ### [.mergePartialsAsync](lib/plugins/context.js#L350) Merge "partials" view types. This is necessary for template engines have no support for partials or only support one type of partials. **Params** * `options` **{Object}**: Optionally pass an array of `viewTypes` to include on `options.viewTypes` * `callback` **{Function}**: Function that exposes `err` and `partials` parameters *** ### Middleware Control the entire render cycle, with simple-to-use routes and middleware. **Example** ```js var router = new app.Router(); var route = new app.Route(); ``` ### [.handle](node_modules/base-routes/index.js#L55) Handle a middleware `method` for `file`. **Params** * `method` **{String}**: Name of the router method to handle. See [router methods](./docs/router.md) * `file` **{Object}**: View object * `callback` **{Function}**: Callback function * `returns` **{undefined}** **Example** ```js app.handle('customMethod', file, callback); ``` ### [.handleOnce](node_modules/base-routes/index.js#L109) Run the given middleware handler only if the file has not already been handled by `method`. **Params** * `method` **{Object}**: The name of the handler method to call. * `file` **{Object}** * `returns` **{undefined}** **Example** ```js app.handleOnce('onLoad', file, callback); ``` ### [.route](node_modules/base-routes/index.js#L193) Create a new Route for the given path. Each route contains a separate middleware stack. See the [route API documentation][route-api] for details on adding handlers and middleware to routes. **Params** * `path` **{String}** * `returns` **{Object}**: Returns the instance for chaining. **Example** ```js app.create('posts'); app.route(/blog/) .all(function(file, next) { // do something with file next(); }); app.post('whatever', {path: 'blog/foo.bar', content: 'bar baz'}); ``` ### [.param](node_modules/base-routes/index.js#L220) Add callback triggers to route parameters, where `name` is the name of the parameter and `fn` is the callback function. **Params** * `name` **{String}** * `fn` **{Function}** * `returns` **{Object}**: Returns the instance for chaining. **Example** ```js app.param('title', function(view, next, title) { //=> title === 'foo.js' next(); }); app.onLoad('/blog/:title', function(view, next) { //=> view.path === '/blog/foo.js' next(); }); ``` ### [.all](node_modules/base-routes/index.js#L243) Special route method that works just like the `router.METHOD()` methods, except that it matches all verbs. **Params** * `path` **{String}** * `callback` **{Function}** * `returns` **{Object}** `this`: for chaining **Example** ```js app.all(/\.hbs$/, function(view, next) { // do stuff to view next(); }); ``` ### [.handler](node_modules/base-routes/index.js#L265) Add a router handler method to the instance. Interchangeable with the [handlers](#handlers) method. **Params** * `method` **{String}**: Name of the handler method to define. * `returns` **{Object}**: Returns the instance for chaining **Example** ```js app.handler('onFoo'); // or app.handler(['onFoo', 'onBar']); ``` ### [.handlers](node_modules/base-routes/index.js#L284) Add one or more router handler methods to the instance. **Params** * `methods` **{Array|String}**: One or more method names to define. * `returns` **{Object}**: Returns the instance for chaining **Example** ```js app.handlers(['onFoo', 'onBar', 'onBaz']); // or app.handlers('onFoo'); ``` *** ### [.isApp](lib/plugins/is.js#L33) Static method that returns true if the given value is a `templates` instance (`App`). **Params** * `val` **{Object}**: The value to test. * `returns` **{Boolean}** **Example** ```js var templates = require('templates'); var app = templates(); templates.isApp(templates); //=> false templates.isApp(app); //=> true ``` ### [.isCollection](lib/plugins/is.js#L55) Static method that returns true if the given value is a templates `Collection` instance. **Params** * `val` **{Object}**: The value to test. * `returns` **{Boolean}** **Example** ```js var templates = require('templates'); var app = templates(); app.create('pages'); templates.isCollection(app.pages); //=> true ``` ### [.isViews](lib/plugins/is.js#L77) Static method that returns true if the given value is a templates `Views` instance. **Params** * `val` **{Object}**: The value to test. * `returns` **{Boolean}** **Example** ```js var templates = require('templates'); var app = templates(); app.create('pages'); templates.isViews(app.pages); //=> true ``` ### [.isList](lib/plugins/is.js#L100) Static method that returns true if the given value is a templates `List` instance. **Params** * `val` **{Object}**: The value to test. * `returns` **{Boolean}** **Example** ```js var templates = require('templates'); var List = templates.List; var app = templates(); var list = new List(); templates.isList(list); //=> true ``` ### [.isGroup](lib/plugins/is.js#L123) Static method that returns true if the given value is a templates `Group` instance. **Params** * `val` **{Object}**: The value to test. * `returns` **{Boolean}** **Example** ```js var templates = require('templates'); var Group = templates.Group; var app = templates(); var group = new Group(); templates.isGroup(group); //=> true ``` ### [.isView](lib/plugins/is.js#L148) Static method that returns true if the given value is a templates `View` instance. **Params** * `val` **{Object}**: The value to test. * `returns` **{Boolean}** **Example** ```js var templates = require('templates'); var app = templates(); templates.isView('foo'); //=> false var view = app.view('foo', {content: '...'}); templates.isView(view); //=> true ``` ### [.isItem](lib/plugins/is.js#L173) Static method that returns true if the given value is a templates `Item` instance. **Params** * `val` **{Object}**: The value to test. * `returns` **{Boolean}** **Example** ```js var templates = require('templates'); var app = templates(); templates.isItem('foo'); //=> false var view = app.view('foo', {content: '...'}); templates.isItem(view); //=> true ``` ### [.isVinyl](lib/plugins/is.js#L200) Static method that returns true if the given value is a vinyl `File` instance. **Params** * `val` **{Object}**: The value to test. * `returns` **{Boolean}** **Example** ```js var File = require('vinyl'); var templates = require('templates'); var app = templates(); var view = app.view('foo', {content: '...'}); templates.isVinyl(view); //=> true var file = new File({path: 'foo', contents: new Buffer('...')}); templates.isVinyl(file); //=> true ``` *** ## More examples This is just a very basic glimpse at the `templates` API! ```js var templates = require('templates'); var app = templates(); // create a collection app.create('pages'); // add views to the collection app.page('a.html', {content: 'this is <%= foo %>'}); app.page('b.html', {content: 'this is <%= bar %>'}); app.page('c.html', {content: 'this is <%= baz %>'}); app.pages.getView('a.html') .render({foo: 'home'}, function (err, view) { //=> 'this is home' }); ``` ## History ### v0.24.0 * Bumps [base-data](https://github.com/node-base/base-data) which removed `renameKey` option used when loading data. Use the `namespace` option instead. ### v0.23.0 * Bumps [base-engine][] to fix a bug in [engine-cache](https://github.com/jonschlinkert/engine-cache). ### v0.22.2 * fixes `List` bug that was caused collection helpers to explode ### v0.22.0 There should be no breaking changes in this release. If you experience a regression, please [create an issue](../../issues). * Externalizes a few core plugins to: [base-helpers](https://github.com/node-base/base-helpers), [base-routes](https://github.com/node-base/base-routes), and [base-engine][]. The goal is to allow you to use only the plugins you need in your builds. * Improvements to lookup functions: `app.getView()` and `app.find()` * Bumps [base](https://github.com/node-base/base) to take advantages of code optimizations. ### v0.21.0 **Breaking changes** * 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. **Non-breaking** * The `View` and `Item` class have been externalized to modules [vinyl-item](https://github.com/jonschlinkert/vinyl-item) and [vinyl-view](https://github.com/jonschlinkert/vinyl-view) so they can be used in other libraries. ### 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 * Removed `debug` methods and related code * Improve layout handling with respect to template types (`partial`, `renderable` and `layout`) * Update dependencies ### v0.16.0 * Improved context handling * Ensure collection middleware is handled [after app middleware](https://github.com/jonschlinkert/templates/commit/f47385f5172a2773c3ab2a969ebfccc533ec5e27) ### v0.15.0 * removes `.removeItem` method that was deprecated in v0.10.7 from `List` * `.handleView` is deprecated in favor of `.handleOnce` and will be removed in a future version. Start using `.handleOnce` now. * adds a static `Templates.setup()` method for initializing any setup code that should have access to the instance before any other use code is run. * upgrade to [base-data](https://github.com/node-base/base-data) v0.4.0, which adds `app.option.set`, `app.option.get` and `app.option.merge` ### v0.14.0 Although 99% of users won't be effected by the changes in this release, there were some **potentially breaking changes**. * The `render` and `compile` methods were streamlined, making it clear that `.mergePartials` should not have been renamed to `mergePartialsSync`. So that change was reverted. * Helper context: Exposes a `this.helper` object to the context in helpers, which has the helper name and options that were set specifically for that helper * Helper context: Exposes a `this.view` object to the context in helpers, which is the current view being rendered. This was (and still is) always expose on `this.context.view`, but it makes sense to add this to the root of the context as a convenience. We will deprecate `this.context.view` in a future version. * Helper context: `.get`, `.set` and `.merge` methods on `this.options`, `this.context` and the `this` object in helpers. ### v0.13.0 * All template handling is async by default. Instead of adding `.compileSync`, we felt that it made more sense to add `.compileAsync`, since `.compile` is a public method and most users will expect it to be sync, and `.compile` methods with most engines are typically sync. In other words, `.compileAsync` probably won't be seen by most users, but we wanted to explain the decision to go against node.js naming conventions. * Improved layout detection and handling ### v0.12.0 * Adds helper methods, [.hasAsyncHelper](#hasasynchelper), [.hasHelper](#hashelper), [.getAsyncHelper](#getasynchelper), and [.getHelper](#gethelper) * Ensures that both collection and app routes are handled when both are defined for a view ### v0.11.0 * Default `engine` can now be defined on `app` or a collection using using `app.option('engine')`, `views.option('engine')` * Default `layout` can now defined using `app.option('layout')`, `views.option('layout')`. No changes have been made to `view.layout`, it should work as before. Resolves [issue/#818](../../issues/818) * Improves logic for finding a layout, this should make layouts easier to define and find going forward. * The built-in `view` helper has been refactored completely. The helper is now async and renders the view before returning its content. * Adds `isApp`, `isViews`, `isCollection`, `isList`, `isView`, `isGroup`, and `isItem` static methods. All return true when the given value is an instance of the respective class. * Adds `deleteItem` method to List and Collection, and `deleteView` method to Views. * Last, the static `_.proto` property which is only exposed for unit tests was renamed to `_.plugin`. ### v0.10.7 * Force-update [base](https://github.com/node-base/base) to v0.6.4 to take advantage of `isRegistered` feature. ### v0.10.6 * Re-introduces fs logic to `getView`, now that the method has been refactored to be faster. ### v0.10.0 * `getView` method no longer automatically reads views from the file system. This was undocumented before and, but it's a breaking change nonetheless. The removed functionality can easily be done in a plugin. ### v0.9.5 * Fixes error messages when no engine is found for a view, and the view does not have a file extension. ### v0.9.4 * Fixes a lookup bug in render and compile that was returning the first view that matched the given name from _any_ collection. So if a partial and a page shared the same name, if the partial was matched first it was returned. Now the `renderable` view is rendered (e.g. page) ### v0.9.0 * _breaking change_: changes parameters on `app.context` method. It now only accepts two arguments, `view` and `locals`, since `ctx` (the parameter that was removed) was technically being merged in twice. ### v0.8.0 * Exposes `isType` method on `view`. Shouldn't be any breaking changes. ### v0.7.0 * _breaking change_: renamed `.error` method to `.formatError` * adds `mergeContext` option * collection name is now emitted with `view` and `item` as the second argument * adds `isType` method for checking the `viewType` on a collection * also now emits an event with the collection name when a view is created ### v0.5.1 * fixes bug where `default` layout was automatically applied to partials, causing an infinite loop in rare cases. ## About ### Related projects * [assemble](https://www.npmjs.com/package/assemble): Get the rocks out of your socks! Assemble makes you fast at creating web projects… [more](https://github.com/assemble/assemble) | [homepage](https://github.com/assemble/assemble "Get the rocks out of your socks! Assemble makes you fast at creating web projects. Assemble is used by thousands of projects for rapid prototyping, creating themes, scaffolds, boilerplates, e-books, UI components, API documentation, blogs, building websit") * [en-route](https://www.npmjs.com/package/en-route): Routing for static site generators, build systems and task runners, heavily based on express.js routes… [more](https://github.com/jonschlinkert/en-route) | [homepage](https://github.com/jonschlinkert/en-route "Routing for static site generators, build systems and task runners, heavily based on express.js routes but works with file objects. Used by Assemble, Verb, and Template.") * [engine](https://www.npmjs.com/package/engine): Template engine based on Lo-Dash template, but adds features like the ability to register helpers… [more](https://github.com/jonschlinkert/engine) | [homepage](https://github.com/jonschlinkert/engine "Template engine based on Lo-Dash template, but adds features like the ability to register helpers and more easily set data to be used as context in templates.") * [layouts](https://www.npmjs.com/package/layouts): Wraps templates with layouts. Layouts can use other layouts and be nested to any depth… [more](https://github.com/doowb/layouts) | [homepage](https://github.com/doowb/layouts "Wraps templates with layouts. Layouts can use other layouts and be nested to any depth. This can be used 100% standalone to wrap any kind of file with banners, headers or footer content. Use for markdown, HTML, handlebars views, lo-dash templates, etc. La") * [verb](https://www.npmjs.com/package/verb): Documentation generator for GitHub projects. Verb is extremely powerful, easy to use, and is used… [more](https://github.com/verbose/verb) | [homepage](https://github.com/verbose/verb "Documentation generator for GitHub projects. Verb is extremely powerful, easy to use, and is used on hundreds of projects of all sizes to generate everything from API docs to readmes.") ### Contributing Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new). ### Building docs _(This document was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme) (a [verb](https://github.com/verbose/verb) generator), please don't edit the readme directly. Any changes to the readme must be made in [.verb.md](.verb.md).)_ To generate the readme and API documentation with [verb](https://github.com/verbose/verb): ```sh $ npm install -g verb verb-generate-readme && verb ``` ### Running tests Install dev dependencies: ```sh $ npm install -d && npm test ``` ### Author **Jon Schlinkert** * [github/jonschlinkert](https://github.com/jonschlinkert) * [twitter/jonschlinkert](http://twitter.com/jonschlinkert) ### License Copyright © 2016, [Jon Schlinkert](https://github.com/jonschlinkert). Released under the [MIT license](https://github.com/jonschlinkert/templates/blob/master/LICENSE). *** _This file was generated by [verb](https://github.com/verbose/verb), v0.9.0, on July 23, 2016._