UNPKG

templates

Version:

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.

2,138 lines (1,387 loc) 63 kB
# templates [![NPM version](https://img.shields.io/npm/v/templates.svg?style=flat)](https://www.npmjs.com/package/templates) [![NPM monthly downloads](https://img.shields.io/npm/dm/templates.svg?style=flat)](https://npmjs.org/package/templates) [![NPM total downloads](https://img.shields.io/npm/dt/templates.svg?style=flat)](https://npmjs.org/package/templates) [![Linux Build Status](https://img.shields.io/travis/jonschlinkert/templates.svg?style=flat&label=Travis)](https://travis-ci.org/jonschlinkert/templates) [![Windows Build Status](https://img.shields.io/appveyor/ci/jonschlinkert/templates.svg?style=flat&label=AppVeyor)](https://ci.appveyor.com/project/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) _(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](https://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#L200) 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#L240) 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#L366) 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#L89) 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#L110) 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#L130) 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#L147) 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#L166) 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#L184) 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#L207) 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#L120) 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#L322) 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#L363) 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#L32) Create an instance of `Item`. Optionally pass a default object to use. See [vinyl](https://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#L215) 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#L237) 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#L120) 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#L322) 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#L363) 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#L27) 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#L132) 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. * `next` **{Function}**: Optionally pass a callback function as the last argument to load the view asynchronously. This will also ensure that `.onLoad` middleware is executed asynchronously. * `returns` **{Object}**: returns the `view` instance. **Example** ```js collection.setView('foo', {content: 'bar'}); // or, optionally async collection.setView('foo', {content: 'bar'}, function(err, view) { // `err` errors from `onLoad` middleware // `view` the view object after `onLoad` middleware has run }); ``` ### [.setView](lib/views.js#L174) 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#L191) 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#L226) 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#L250) 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#L282) 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#L319) 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#L349) 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#L396) 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#L120) 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#L322) 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#L363) 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#L120) 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#L322) 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#L363) 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#L118) 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#L156) 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#L176) 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#L205) 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#L240) 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#L256) 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#L300) Get a specific item from the list by `key`. **Params** * `key` **{String}**: The item name/key. * `returns` **{Object}** **Example** ```js list.getItem('foo.html'); //=> '<Item <foo.html>>' ``` ### [.getView](lib/list.js#L319) Proxy for `getItem` **Params** * `key` **{String}**: Pass the key of the `item` to get. * `returns` **{Object}** **Example** ```js list.getItem('foo.html'); //=> '<Item "foo.html" <buffer e2 e2 e2>>' ``` ### [.deleteItem](lib/list.js#L333) 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'); ``` ### [.deleteItems](lib/list.js#L352) Remove one or more items from the list. **Params** * `items` **{Object|String|Array}**: List of items to remove. **Example** ```js list.deleteItems(['a.html', 'b.html']); ``` ### [.extendItem](lib/list.js#L372) 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 ### [.filter](lib/list.js#L390) Filters list `items` using the given `fn` and returns a new array. * `returns` **{Object}**: Returns a filtered array of items. **Example** ```js var items = list.filter(function(item) { return item.data.title.toLowerCase() !== 'home'; }); ``` ### [.sortBy](lib/list.js#L411) 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 ``` ### [.groupBy](lib/list.js#L449) 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'); ``` ### [.paginate](lib/list.js#L476) 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#L120) 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#L322) 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#L363) 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#L275) 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#L120) 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#L322) 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#L363) 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 ### key Starting with v0.25.0, changelog entries will be categorized using the following labels from [keep-a-changelog](https://github.com/olivierlacan/keep-a-changelog)_: * `added`: for new features * `changed`: for changes in existing functionality * `deprecated`: for once-stable features removed in upcoming releases * `removed`: for deprecated features removed in this release * `fixed`: for any bug fixes ### [1.1.0](https://github.com/jonschlinkert/templates/compare/1.0.0...1.1.0) **fixed** Reverts layout changes from 1.0 to fix block-layout-nesting bug. There is a bug causing child blocks to be promoted up to ancestors when a nested layout/block is defined. It's not a common scenario, and probably hasn't been encountered in the wild yet since blocks were just introduced and haven't been documented yet. However, it's a bad bug, and would cause major problems if it surfaced. The good news is that I know how to fix it. Bad news is that it will be time consuming and I need to make other changes before I get to that fix. Thus, in the meantime the best course of action is removing the blocks code. ### [1.0.0](https://github.com/jonschlinkert/templates/compare/0.25.2...1.0.0) **Added** * Templates now uses [dry](https://github.com/jonschlinkert/dry) for handling layouts * Advanced template-inheritance features, like `extends` and blocks! See [dry](https://github.com/jonschlinkert/dry) documentation for details. ### [0.25.2](https://github.com/jonschlinkert/templates/compare/0.25.1...0.25.2) **Fixed** * Correctly handles arguments for the built-in singular helper when used with Handlebars. ### [0.25.1](https://github.com/jonschlinkert/templates/compare/0.25.0...0.25.1) **Fixed** * Ensures the template rendering engine's context is preserved. ### [0.25.0](https://