Package Exports
- handlebars-layouts
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (handlebars-layouts) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
handlebars-layouts
Handlebars helpers which implement layout blocks similar to Jade, Jinja, Swig, and Twig.
Install
With Node.js:
$ npm install handlebars-layoutsWith Bower:
$ bower install shannonmoeller/handlebars-layoutsHelpers
{{#extend [partial] [key=value ...]}}
partialString- Name of partial to render.attributesObject(Optional) - Arbitrary values that will be added to the partial data context.
Loads a layout partial of a given name and defines block content.
{{#extend "layout" keywords="handlebars,hbs,layout"}}
{{#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:
class Page extends Layout {
constructor() {
this.keywords = 'handlebars,hbs,layout';
}
title() {
return 'Example - ' + super();
}
}{{#embed [partial] [key=value ...]}}
partialString- Name of partial to render.attributesObject(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.
{{#extend "layout"}}
{{#content "body"}}
{{#embed "gallery"}}
{{#content "body"}}
<img src="1.png" alt="" />
<img src="2.png" alt="" />
{{/content}}
{{/embed}}
{{#embed "modal" foo="bar" name=user.fullName}}
{{#content "title" mode="prepend"}}Image 1 - {{/content}}
{{#content "body"}}<img src="1.png" alt="" />{{/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:
class Page extends Layout {
body(data) {
var gallery = new Gallery();
gallery.replaceBody('<img src="1.png" alt="" />\n<img src="2.png" alt="" />');
var modal = new Modal({
foo: 'bar',
name: data.user.fullName
});
modal.prependTitle('Image 1 - ');
modal.replaceBody('<img src="1.png" alt="" />');
return gallery.toString() + modal.toString();
}
}{{#block [name]}}
nameString- 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.
{{#block "header"}}
<h1>Hello World</h1>
{{/block}}
{{#block "main"}}
<p>Lorem ipsum...</p>
{{/block}}
{{#block "footer"}}
<p>© 1970</p>
{{/block}}Default block content is optional, and may be omitted.
<h1>{{{block "title"}}}</h1>
<p>{{{block "description"}}}</p>{{#content [name] mode="(append|prepend|replace)"}}
nameString- Identifier of the block to modify.modeString(Optional) - Means of providing block content. Default:replace.
Sets block content, optionally appending or prepending using the mode attribute.
Layout:
<html>
...
<body>
{{#block "header"}}
<h1>Hello World</h1>
{{/block}}
{{#block "main"}}
<p>Lorem ipsum.</p>
{{/block}}
{{#block "footer"}}
<p>© 1999</p>
{{/block}}
</body>
</html>Page:
{{#extend "layout"}}
{{#content "header"}}
<h1>Goodnight Moon</h1>
{{/content}}
{{#content "main" mode="append"}}
<p>Dolor sit amet.</p>
{{/content}}
{{#content "footer" mode="prepend"}}
<p>MIT License</p>
{{/content}}
{{/extend}}Output:
<html>
...
<body>
<h1>Goodnight Moon</h1>
<p>Lorem ipsum.</p>
<p>Dolor sit amet.</p>
<p>MIT License</p>
<p>© 1999</p>
</body>
</html>Content is optional, and may be omitted. This will cause the main block to be replaced with an empty string, clearing out any default content.
{{{content "main"}}}Api
Helpers are registered by passing in your instance of Handlebars. This allows you to selectively register the helpers on various instances of Handlebars.
layouts(handlebars)
handlebarsHandlebars- An instance of Handlebars.
var handlebars = require('handlebars'),
layouts = require('handlebars-layouts');
layouts(handlebars);layouts.register(handlebars)
handlebarsHandlebars- An instance of Handlebars.
Helpers are also exposed via a register method for use with Assemble.
var handlebars = require('handlebars'),
layouts = require('handlebars-layouts');
layouts.register(handlebars);
// or
grunt.initConfig({
assemble: {
options: {
helpers: ['path/to/handlebars-layouts.js']
}
}
});Example
Layout Partial
<!doctype html>
<html lang="en-us">
<head>
{{#block "head"}}
<title>{{title}}</title>
<link rel="stylesheet" href="assets/css/screen.css" />
{{/block}}
</head>
<body>
<div class="site">
<div class="site-hd" role="banner">
{{#block "header"}}
<h1>{{title}}</h1>
{{/block}}
</div>
<div class="site-bd" role="main">
{{#block "body"}}
<h2>Hello World</h2>
{{/block}}
</div>
<div class="site-ft" role="contentinfo">
{{#block "footer"}}
<small>© 2013</small>
{{/block}}
</div>
</div>
{{#block "foot"}}
<script src="assets/js/controllers/home.js"></script>
{{/block}}
</body>
</html>Template
{{#extend "layout"}}
{{#content "head" mode="append"}}
<link rel="stylesheet" href="assets/css/home.css" />
{{/content}}
{{#content "body"}}
<h2>Welcome Home</h2>
<ul>
{{#items}}
<li>{{.}}</li>
{{/items}}
</ul>
{{/content}}
{{#content "foot" mode="prepend"}}
<script src="assets/js/analytics.js"></script>
{{/content}}
{{/extend}}Putting Them Together
// Load Handlebars
var Handlebars = require('handlebars');
// Register helpers
require('handlebars-layouts')(Handlebars);
// Register partials
Handlebars.registerPartial('layout', fs.readFileSync('layout.html', 'utf8'));
// Compile template
var template = Handlebars.compile(fs.readFileSync('template.html', 'utf8'));
// Render template
var output = template({
title: 'Layout Test',
items: [
'apple',
'orange',
'banana'
]
});
console.log(output);Output (prettified for readability)
<!doctype html>
<html lang="en-us">
<head>
<title>Layout Test</title>
<link rel="stylesheet" href="assets/css/screen.css" />
<link rel="stylesheet" href="assets/css/home.css" />
</head>
<body>
<div class="site">
<div class="site-hd" role="banner">
<h1>Layout Test</h1>
</div>
<div class="site-bd" role="main">
<h2>Welcome Home</h2>
<ul>
<li>apple</li>
<li>orange</li>
<li>banana</li>
</ul>
</div>
<div class="site-ft" role="contentinfo">
<small>© 2013</small>
</div>
</div>
<script src="assets/js/analytics.js"></script>
<script src="assets/js/controllers/home.js"></script>
</body>
</html>Test
$ npm testContribute
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.
License
MIT