template

Render templates using any engine. Supports, layouts, pages, partials and custom template types. Use template helpers, middleware, routes, loaders, and lots more. Powers assemble, verb and other node.js apps.

template

Render templates using any engine. Supports, layouts, pages, partials and custom template types. Use template helpers, middleware, routes, loaders, and lots more. Powers assemble, verb and other node.js apps.

Go to the API documentation

  • ~100% test coverage (as of Apr. 23, 2015) with ~500 unit tests
  • Render templates with any engine, including any consolidate, transformers, or any compatible engine. Or, create your own!
  • Create custom template types. Built-in types are page, layout and partial, but you can create special types for any use case.
  • Custom loaders. Loaders are simple functions that change how templates are loaded and can be used with template types, or individual templates.

Install with npm

npm i template --save
var Template = require('template');
var template = new Template();
template.page('home.tmpl', 'This home page.');
 
// add locals 
template.page('home.tmpl', 'The <%= title %> page', {title: 'home'});

Debugging

Template

Create a new instance of Template, optionally passing default options to initialize with.

  • options {Object}: Options to initialize with.

Example:

var Template = require('template');
var template = new Template();

.transform

Assign transform fn to name or return the value of name if no other arguments are passed.

  • name {String}: The name of the transform to add.
  • fn {Function}: The actual transform function.
  • returns {Object}: Returns Template for chaining.

Transforms are run immediately during init, and are used to extend or modify the cache.data object, but really anything on the this object can be tranformed.

template.transform('username', function(app) {
  var url = app.cache.data.author.url.split('/');
  app.cache.data.username = url[2];
});

.route

Proxy to the engine Router#route() Returns a new Route instance for the path.

  • path {String}

Routes are isolated middleware stacks for specific paths. See the Route api docs for details.

.param

Proxy to Router#param() with one added api feature. The name parameter can be an array of names.

  • name {String|Array}
  • fn {Function}
  • returns {Object} Template: for chaining

See the Router#param() docs for more details.

Delegate .METHOD(...) calls to router.METHOD(...)

.all

Special-cased "all" method, applying the given route path, middleware, and callback.

  • path {String}
  • {Function}: Callback
  • returns {Object} Template: for chaining
template.all(/\.md$/, function (filenext) {
  // do stuff next(); 
});

.engine

  • exts {String|Array}: File extension or array of extensions.
  • fn {Function|Object}: or options
  • options {Object}
  • returns {Object} Template: to enable chaining

<%= docs("api-engine") %>

Register the given view engine callback fn as ext. If only ext is passed, the engine registered for ext is returned. If no ext is passed, the entire cache is returned.

.getEngine

Get the engine settings registered for the given ext.

  • ext {String}: The engine to get.
  • returns {Object}: Object with methods and settings for the specified engine.

<%= docs("api-getEngine") %>

template.getEngine('.html');

.helper

Register generic template helpers that can be used with any engine.

  • key {String}: Helper name
  • fn {Function}: Helper function.

Helpers registered using this method will be passed to every engine, so this method is best for generic javascript functions - unless you want to see Lo-Dash blow up from Handlebars.SafeString.

template.helper('lower', function(str) {
  return str.toLowerCase();
});

.helpers

Register multiple helpers.

  • helpers {Object|Array}: Object, array of objects, or glob patterns.
template.addHelpers({
  afunction() {},
  bfunction() {},
  cfunction() {},
});

.asyncHelper

Register generic async template helpers that are not specific to an engine.

  • name {String}: Helper name.
  • fn {Function}: Helper function

As with the sync version, helpers registered using this method will be passed to every engine, so this method is best for generic javascript functions.

template.asyncHelper('lower', function(strnext) {
  str = str.toLowerCase();
  next();
});

.asyncHelpers

Register multiple async helpers.

  • helpers {Object|Array}: Object, array of objects, or glob patterns.
template.addAsyncHelpers({
  afunction() {},
  bfunction() {},
  cfunction() {},
});

.engineHelpers

Register an object of helpers for the given ext (engine).

  • ext {String}: The engine to register helpers with.
  • returns {Object}: Object of helpers for the specified engine.
template.helpers(require('handlebars-helpers'));

.validate

  • template {String}: a template object

Validate a template object to ensure that it has the properties expected for applying layouts, choosing engines, and so on.

.view

  • collection {String}
  • name {String}
  • returns: {Object}

Get the given view collection from views. Optionally pass a name to get a specific template from the collection.

.getType

Get all views of the given [type]. Valid values are renderable, layout or partial.

  • type {String}
  • opts {Object}
var pages = template.getType('renderable');
//=> { pages: { 'home.hbs': { ... }, 'about.hbs': { ... }}, posts: { ... }} 

.mergeType

Merge all collections of the given type into a single collection. e.g. partials and includes would be merged.

  • type {String}: The template type to search.
  • keys {String}: Optionally pass an array of view collection names

If an array of collections is passed, only those collections will be merged and the order in which the collections are defined in the array will be respected.

.mergeLayouts

  • type {String}: The template type to search.
  • collections {String}: Optionally pass an array of collections

Merge all layout collections based on user-defined options.

.mergePartials

Default method for determining how partials are to be passed to engines. By default, all partial collections are merged onto a single partials object. To keep each collection on a separate object, you can do template.disable('mergePartials').

  • locals {Object}: Locals should have layout delimiters, if defined
  • returns: {Object}

If you want to control how partials are merged, you can also pass a function to the mergePartials option:

template.option('mergePartials', function(locals) {
  // do stuff 
});

.findRenderable

Search all renderable subtypes, returning the first template with the given key.

  • key {String}: The template to search for.

  • subtypes {Array}

    • If key is not found an error is thrown.
    • Optionally limit the search to the specified subtypes.

.findLayout

Search all layout subtypes, returning the first template with the given key.

  • key {String}: The template to search for.

  • subtypes {Array}

    • If key is not found an error is thrown.
    • Optionally limit the search to the specified subtypes.

.findPartial

Search all partial subtypes, returning the first template with the given key.

  • key {String}: The template to search for.

  • subtypes {Array}

    • If key is not found an error is thrown.
    • Optionally limit the search to the specified subtypes.

.lookup

  • plural {String}: The view collection to search.
  • name {String}: The name of the template.
  • ext {String}: Optionally pass a file extension to append to name

Convenience method for finding a template by name on the given collection. Optionally specify a file extension.

.create

Create a new view collection and associated convience methods.

  • subtype {String}: Singular name of the collection to create, e.g. page.

  • plural {String}: Plural name of the collection, e.g. pages.

  • options {Object}: Options for the collection.

    • isRenderable {Boolean}: Templates that may be rendered at some point
    • isLayout {Boolean}: Templates to be used as layouts
    • isPartial {Boolean}: Templates to be used as partial views or includes
  • stack {Function|Array}: Loader function or functions to be run for every template of this type.

  • returns {Object} Template: to enable chaining.

Note that when you only specify a name for the type, a plural form is created automatically (e.g. page and pages). However, you can define the plural form explicitly if necessary.

.compileTemplate

  • template {Object}: The template object with content to compile.
  • options {Object}: Options to pass along to the engine when compile. May include a context property to bind to helpers.
  • returns {Object}: Template object to enable chaining.

Compile content on the given template object with the specified engine options.

.compile

  • file {Object|String}: String or normalized template object.
  • options {Object}
  • isAsync {Boolean}: Load async helpers
  • returns {Function}: Compiled function.

Compile content with the given options.

.compileString

Compile the given string with the specified options.

  • str {String}: The string to compile.
  • options {Object}: Options to pass to registered view engines.
  • async {Boolean}: Load async helpers
  • returns: {Function}

The primary purpose of this method is to get the engine before passing args to .compileBase().

.renderTemplate

  • template {Object}: The template object with content to render.
  • locals {Object}: Locals and/or options to pass to registered view engines.
  • returns: {String}

Render content on the given template object with the specified engine options and callback.

.render

  • file {Object|String}: String or normalized template object.
  • locals {Object}: Locals and/or options to pass to registered view engines.
  • returns {String}: Rendered string.

Render content with the given options and optional callback.

.renderString

Render the given string with the specified locals and callback.

  • str {String}: The string to render.
  • locals {Object}: Locals and/or options to pass to registered view engines.
  • returns: {String}

The primary purpose of this method is to get the engine before passing args to .renderBase().

.renderSubtype

Returns a render function for rendering templates of the given subtype.

  • plural {String}: Template subtype, e.g. pages

  • str {String}: The string to render.

  • locals {Object}: Locals and/or options to pass to registered view engines.

  • returns {Function} params

  • returns {String} string: The rendered string.

Mostly used internally as a private method, but it's exposed as a public method since there are cases when it might be useful, like for rendering templates in a gulp/grunt/assemble plugin.

.renderType

  • str {String}: The string to render.
  • locals {Object}: Locals and/or options to pass to registered view engines.
  • returns: {String}

Render the given string with the specified locals and callback.

Using the default Lo-Dash engine:

template.render('home.tmpl', function(errhtml) {
  if (err) throw err;
  console.log(html); //=> 'The home page.' 
});

Or you can pass a string (non-cached template):

template.render('foo bar', function(errhtml) {
  if (err) throw err;
  console.log(html); //=> 'foo bar' 
});

Locals

Pass locals as the second parameter:

template.render('foo <%= bar %>', {bar: 'baz'}, function(errhtml) {
  if (err) throw err;
  console.log(html); //=> 'foo baz' 
});

Register

Examples

// use handlebars to render templates with the `.hbs` extension 
template.engine('hbs', require('engine-handlebars'));
 
// use lo-dash to render templates with the `.tmpl` extension 
template.engine('tmpl', require('engine-lodash'));

Using consolidate.js

You can also use consolidate:

var consolidate = require('consolidate');
template.engine('hbs', consolidate.handlebars);
template.engine('tmpl', consolidate.lodash);

Using a custom function

Example of creating an engine to render .less files:

var less = require('less');
 
template.engine('less', function(stroptionscb) {
  less.render(str, options, function (errres) {
    if (err) { return cb(err); }
    cb(null, res.css);
  });
});

You can also use engine-less.

As glob patterns:

template.pages('pages/*.hbs');
template.pages(['partials/*.hbs', 'includes/*.hbs']);

As key/value pairs:

template.page('home', 'This is home.');
template.page('home', 'This is <%= title %>.', {title: 'home'});
template.page('home', {content: 'This is home.'});
template.page('home', {content: 'This is <%= title %>.', title: 'home'});
template.page('home', {content: 'This is <%= title %>.'}, {title: 'home'});

Note any of the above examples will work with either the singular or plural methods (e.g. page/pages)

Built-in template types are:

  • page: the default renderable template type
  • layout: the default layout template type
  • partial: the default partial template type

If you need something different, add your own:

template.create('post', { isRenderable: true, isPartial: true });
template.create('section', { isLayout: true });
template.create('include', { isPartial: true });

Setting isRenderable, isLayout and isPartial will add special convenience methods to the new template type. For example, when isRenderable is true, any templates registered for that that type can be rendered directly by passing the name of a template to the .render() method.

Loading custom templates

We can now load posts using the .post() or .posts() methods, the same way that pages or other default templates are loaded:

template.posts('my-blog-post', 'This is content...');

Note: if you create a new template type with a weird plural form, like cactus, you can pass cacti as a second arg. e.g. template.create('cactus', 'cactii')

  1. post will belong to both the renderable and partial types. This means that posts can be used as partials, and they will be "findable" on the cache by the render methods. Renderable templates also get their own render methods, but more on that later.
  2. section will belong to the layout type. This means that any section template can be used as a layout for other templates.
  3. include will belong to the partial type. This means that any include template can be used as partial by other templates.

Every template subtype uses a built-in loader to load and/or resolve templates. However, if you need something different, just add your own.

Pass an array of functions, each can take any arguments, but the last must pass an object to the callback:

template.create('component', { isPartial: true }, [
  function (filepathnext) {
    var str = fs.readFileSync(filepath, 'utf8');
    var file = {};
    file[filepath] = {path: filepath, content: str};
    return file;
  }]
);

Now, every component will use this loader.

template.component('components/navbar.html');
//=> {'components/navbar.html': {path: 'components/navbar.html', content: '...'}}; 

When the last argument passed to a template is an array, or more specifically an array of functions, that array will be concatenated to the loader array for the template's subtype.

Example

template.component('components/navbar.html', [
  function(file) {
    file.data = file.data || {foo: 'bar'};
    return file;
  },
  function(file) {
    file.opts = file.opts || {baz: 'quux'};
    return file;
  }]
});
//=> {navbar: {path: 'components/navbar.html', content: '...', data: {foo: 'bar'}}}; 

As mentioned in the previous section, loader functions may take any arguments long as the last function returns a valid template object.

Valid template object

A valid template object is a key/value pair that looks like this:

// {key: value} 
{'foo.txt': {content: 'this is content'}};
  • key {String}: the unique identifier for the template. Usually a name or the filepath that was used for loading the template
  • value {Object}: the actual template object, value must have the following properties:
    • content {String}: the string to be rendered

Any additional properties may be added. Useful ones are:

  • path {String}: If present, can be used to determine engines, delimiters, etc.
  • ext {String}: Like path, can be used to determine engines, delimiters, etc.
  • options {Object}: If present, options are passed to engines, and can also be useful in determining engines, delimiters, etc.
  • locals {Object}: data to pass to templates

Libraries that are used in Template:

{%= related(['layouts', 'bluebird', 'async', 'config-cache', 'en-route', 'engine-cache', 'helper-cache', 'loader-cache']) %}

Install dev dependencies:

npm i -d && npm test

Install devDependencies:

npm i -&& verb

Pull requests and stars are always welcome. For bugs and feature requests, please create an issue

Jon Schlinkert

Brian Woodward

Copyright (c) 2014-2015 Jon Schlinkert Released under the MIT license.


This file was generated by verb-cli on April 23, 2015.