node package manager


layouts NPM version NPM downloads Build Status

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. Layouts can also be vinyl files.

Table of Contents

(TOC generated by verb using markdown-toc)


Install with npm:

$ npm install --save layouts


var renderLayouts = require('layouts');


Basic example

In this example, two layouts are used:

  • the first layout, one, will wrap the string
  • the second layout, two, will wrap the first layout
var layouts = {
  one: {content: 'one before\n{% body %}\none after', layout: 'two'},
  two: {content: 'two before\n{% body %}\ntwo after'},
// `one` is the name of the first layout to use on the provided string 
renderLayouts('<div>Wrap me with a layout!!!</div>', 'one', layouts);

Results in:

two before
one before
<div>Wrap me with a layout!!!</div>
one after
two after


This example shows how to use nested HTML layouts to wrap content:

var layouts = {};
layouts.base = {
  path: 'base.tmpl',
  content: [
    '<!DOCTYPE html>',
    '<html lang="en">',
    '  <head>',
    '    <meta charset="UTF-8">',
    '    <title>Home</title>',
    '  </head>',
    '  <body>',
    '    {% body %}',
    '  </body>',
// this `nav` layout will be wrapped with the `base` layout 
layouts.nav = {
  path: 'nav.tmpl',
  layout: 'base',
  content: '<nav>\n{% body %}\n</nav>'
// this string will be wrapped with the `nav` layout 
var str = [
  '<ul class="categories">',
  '  <li class="active"> <a href="#"> Development </a> </li>',
  '  <li> <a href="#"> Design </a> </li>',
  '  <li> <a href="#"> Node.js </a> </li>',
// `nav` is the name of the layout to use 
renderLayouts(str, nav, layouts);

Results in something like:

<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8">
      <ul class="categories">
        <li class="active"> <a href="#"> Development </a> </li>
        <li> <a href="#"> Design </a> </li>
        <li> <a href="#"> Node.js </a> </li>


By default, {% body %} is used as the placeholder (insertion point) for content, but this can easily be customized with the following options:

  • layoutDelims: the delimiters to use. This can be a regex, like /{{([^}]+)\}}/, or an array of delimiter strings, like ['{{', '}}']
  • contentTag: the name of the content placeholder tag (defaults to body).



Apply a layout from the layouts object to file.contents. Layouts will be recursively applied until a layout is not defined by the returned file.


  • file {Object}: File object. This can be a plain object or vinyl file.
  • layouts {Object}: Object of file objects to use as "layouts".
  • options {Object}
  • returns {Object}: Returns the original file object with layout(s) applied.


var applyLayout = require('layouts');
var layouts = {};
layouts.default = new File({path: 'default', contents: new Buffer('foo\n{% body %}\nbar')}),
layouts.other = new File({path: 'other', contents: new Buffer('baz\n{% body %}\nqux')});
layouts.other.layout = 'default';
var file = new File({path: 'whatever', contents: new Buffer('inner')});
file.layout = 'other';
applyLayouts(file, layouts);
// foo 
// bar 
// inner 
// baz 
// qux 



Breaking changes

  • The main layouts() function now expects a file object as the first argument. This can be an object with path, layout and contents properties, or a valid vinyl file. See the API docs for more details.


Breaking changes

  • change options.tag to options.contentTag


  • update tests to use assert instead of should


  • All view objects must now have a path property, following vinyl conventions.


Related projects

  • assemble: Get the rocks out of your socks! Assemble makes you fast at creating web projects… more | homepage
  • gulp: The streaming build system | homepage
  • handlebars-layouts: Handlebars helpers which implement layout blocks similar to Jade, Jinja, Swig, and Twig. | homepage
  • inject-snippet: Inject a snippet of code or content into a string. | homepage
  • templates: System for creating and managing template collections, and rendering templates with any node.js template engine… more | homepage
  • verb: Documentation generator for GitHub projects. Verb is extremely powerful, easy to use, and is used… more | homepage
  • vinyl: A virtual file format | homepage


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

Building docs

(This document was generated by verb-generate-readme (a verb generator), please don't edit the readme directly. Any changes to the readme must be made in

To generate the readme and API documentation with verb:

$ npm install -g verb verb-generate-readme && verb

Running tests

Install dev dependencies:

$ npm install -d && npm test


Brian Woodward


Copyright © 2016, Brian Woodward. Released under the MIT license.

This file was generated by verb, v0.9.0, on July 25, 2016.