# `handlebars-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.
## Install
With [Node.js](http://nodejs.org):
$ npm install handlebars-layouts
With [Bower](http://bower.io):
$ bower install shannonmoeller/handlebars-layouts
## API
Helpers are generated by passing in your instance of Handlebars. This allows you to selectively register the helpers on various instances of Handlebars.
### `layouts(handlebars) : Object`
- `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));
```
### `layouts.register(handlebars) : Object`
- `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);
```
## Helpers
### `{{#extend [partial] [context] [key=value ...]}}`
- `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();
}
}
```
### `{{#embed [partial] [context] [key=value ...]}}`
- `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();
}
}
```
### `{{#block [name]}}`
- `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"}}
Lorem ipsum...
{{/block}} {{#block "footer"}}© 1970
{{/block}} ``` ### `{{#content [name] mode="(append|prepend|replace)"}}` - `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"}}Lorem ipsum.
{{/block}} {{#block "footer"}}© 1999
{{/block}} ``` Page: ```handlebars {{#extend "layout"}} {{#content "header"}}Dolor sit amet.
{{/content}} {{#content "footer" mode="prepend"}}MIT License
{{/content}} {{/extend}} ``` Output: ```handlebars ...Lorem ipsum.
Dolor sit amet.
MIT License
© 1999
``` ### Conditional Blocks 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](http://handlebarsjs.com/expressions.html#subexpressions) 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 --}}Left
{{/content}} {{/extend}} ``` Resulting in: ```htmlLeft
Left
{{/content}} {{#content "right"}}Right
{{/content}} {{/extend}} ``` Resulting in: ```htmlLeft
Right