Handlebars helpers which implement layout blocks similar to Jade, Jinja, Nunjucks, Swig, and Twig.
npm install handlebars-layoutshandlebars-layouts[![NPM version][npm-img]][npm-url] [![Downloads][downloads-img]][npm-url] [![Build Status][travis-img]][travis-url] [![Coverage Status][coveralls-img]][coveralls-url] [![Tip][amazon-img]][amazon-url]
Handlebars helpers which implement layout blocks similar to Jade, Jinja, Nunjucks, Swig, and Twig.
With Node.js:
$ npm install handlebars-layouts
With Bower:
$ bower install shannonmoeller/handlebars-layouts
Helpers are generated by passing in your instance of Handlebars. This allows you to selectively register the helpers on various instances of Handlebars.
- handlebars Handlebars - An instance of Handlebars.
Generates an object containing the layout helpers suitible for passing into registerHelper.
``js
var handlebars = require('handlebars'),
layouts = require('handlebars-layouts');
handlebars.registerHelper(layouts(handlebars));
`
- handlebars Handlebars - An instance of Handlebars.
Both generates an object containing the layout helpers and registers them with Handlebars automatically.
`js
var handlebars = require('handlebars'),
layouts = require('handlebars-layouts');
layouts.register(handlebars);
`
- partial String - Name of partial to render.context
- Object _(Optional)_ - A custom context for the partial.attributes
- Object _(Optional)_ - Arbitrary values that will be added to the partial data context.
Loads a layout partial of a given name and defines block content.
`handlebars`
{{#extend "layout" foo="bar"}}
{{#content "title" mode="prepend"}}Example - {{/content}}
{{/extend}}
The {{#extend}} helper allows you to reason about your layouts as you would class extension where the above is equivalent to the following psuedo code:
`js
class Page extends Layout {
constructor() {
this.foo = 'bar';
}
title() {
return 'Example - ' + super();
}
}
`
- partial String - Name of partial to render.context
- Object _(Optional)_ - A custom context for the partial.attributes
- Object _(Optional)_ - Arbitrary values that will be added to the partial data context.
Allows you to load a partial which itself extends from a layout. Blocks defined in embedded partials will not conflict with those in the primary layout.
`handlebars
{{#extend "layout"}}
{{#content "body"}}
{{#embed "gallery"}}
{{#content "body"}}


{{/content}}
{{/embed}}
{{#embed "modal" foo="bar" name=user.fullName}}
{{#content "title" mode="prepend"}}Image 1 - {{/content}}
{{#content "body"}}
{{/content}}
{{/embed}}
{{/content}}
{{/extend}}
`
The {{#embed}} helper allows you to reason about your partials as you would class instantiation where the above is equivalent to the following psuedo code:
`js
class Page extends Layout {
body() {
var gallery = new Gallery();
gallery.replaceBody('
\n
');
var modal = new Modal({
foo: 'bar',
name: this.user.fullName
});
modal.prependTitle('Image 1 - ');
modal.replaceBody('
');
return gallery.toString() + modal.toString();
}
}
`
- name String - Block identifier.
Defines a named block, with optional default content. Blocks may have content appended, prepended, or replaced entirely when extending or embedding. You may append and prepend to the same block multiple times.
`handlebars
{{#block "header"}}
Hello World
{{/block}}
{{#block "main"}}
Lorem ipsum...
{{#block "footer"}}
© 1970
$3
-
name String - Identifier of the block to modify.
- mode String _(Optional)_ - Means of providing block content. Default: replace.Sets block content, optionally appending or prepending using the
mode attribute.Layout:
`handlebars
...
{{#block "header"}}
Hello World
{{/block}} {{#block "main"}}
Lorem ipsum.
{{/block}} {{#block "footer"}}
© 1999
{{/block}}
`Page:
`handlebars
{{#extend "layout"}} {{#content "header"}}
Goodnight Moon
{{/content}} {{#content "main" mode="append"}}
Dolor sit amet.
{{/content}} {{#content "footer" mode="prepend"}}
MIT License
{{/content}}{{/extend}}
`Output:
`handlebars
...
Goodnight Moon
Lorem ipsum.
Dolor sit amet.
MIT License
© 1999
`$3
There are times where you need to wrap a block with an element or use a different class depending on whether content has been provided for a block. For this purpose, the
content helper may be called as a subexpression to check whether content has been provided for a block.For example, you may wish to have an optional column in a grid layout:
`handlebars
{{!-- layout.hbs --}}
{{{block "left"}}}
{{#if (content "right")}}
{{{block "right"}}}
{{/if}}
`For a page that only needs a left column, you may omit defining content for the
right block:`handlebars
{{!-- page.html --}}
{{#extend "layout"}} {{#content "left"}}
Left
{{/content}}{{/extend}}
`Resulting in:
`html
Left
`For a page with two columns, simply define content for both blocks:
`handlebars
{{!-- page.html --}}
{{#extend "layout"}} {{#content "left"}}
Left
{{/content}} {{#content "right"}}
Right
{{/content}}{{/extend}}
`Resulting in:
`html
Left
Right
`Example
$3
`handlebars
{{#block "head"}}
{{title}}
{{/block}}
{{#block "header"}}
{{title}}
{{/block}}
{{#block "body"}}
Hello World
{{/block}}
{{#block "footer"}}
© 2013
{{/block}}
{{#block "foot"}}
{{/block}}
`$3
`handlebars
{{#extend "layout"}}
{{#content "head" mode="append"}}
{{/content}} {{#content "body"}}
Welcome Home
{{#items}}
- {{.}}
{{/items}}
{{/content}} {{#content "foot" mode="prepend"}}
{{/content}}
{{/extend}}
`$3
`js
var handlebars = require('handlebars');
var layouts = require('handlebars-layouts');// Register helpers
handlebars.registerHelper(layouts(handlebars));
// Register partials
handlebars.registerPartial('layout', fs.readFileSync('layout.hbs', 'utf8'));
// Compile template
var template = handlebars.compile(fs.readFileSync('page.html', 'utf8'));
// Render template
var output = template({
title: 'Layout Test',
items: [
'apple',
'orange',
'banana'
]
});
console.log(output);
`$3
`handlebars
Layout Test
Layout Test
Welcome Home
- apple
- orange
- banana
© 2013
``[![Tasks][waffle-img]][waffle-url]
Standards for this project, including tests, code coverage, and semantics are enforced with a build tool. Pull requests must include passing tests with 100% code coverage and no linting errors.
$ npm test
----
© 2015 Shannon Moeller
Licensed under MIT
[amazon-img]: https://img.shields.io/badge/tip-jar-yellow.svg?style=flat-square
[amazon-url]: https://www.amazon.com/gp/registry/wishlist/1VQM9ID04YPC5?sort=universal-price
[coveralls-img]: http://img.shields.io/coveralls/shannonmoeller/handlebars-layouts/master.svg?style=flat-square
[coveralls-url]: https://coveralls.io/r/shannonmoeller/handlebars-layouts
[downloads-img]: http://img.shields.io/npm/dm/handlebars-layouts.svg?style=flat-square
[npm-img]: http://img.shields.io/npm/v/handlebars-layouts.svg?style=flat-square
[npm-url]: https://npmjs.org/package/handlebars-layouts
[travis-img]: http://img.shields.io/travis/shannonmoeller/handlebars-layouts.svg?style=flat-square
[travis-url]: https://travis-ci.org/shannonmoeller/handlebars-layouts
[waffle-img]: http://img.shields.io/github/issues/shannonmoeller/handlebars-layouts.svg?style=flat-square
[waffle-url]: http://waffle.io/shannonmoeller/handlebars-layouts