Security News
RubyGems.org Adds New Maintainer Role
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
handlebars-layouts
Advanced tools
Handlebars helpers which implement layout blocks similar to Jade, Jinja, Swig, and Twig.
handlebars-layouts
Handlebars helpers which implement layout blocks similar to Jade, Jinja, 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.
layouts(handlebars) : Object
handlebars
Handlebars
- An instance of Handlebars.Generates an object containing the layout helpers suitible for passing into registerHelper
.
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.
var handlebars = require('handlebars'),
layouts = require('handlebars-layouts');
layouts.register(handlebars);
{{#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.
{{#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:
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.
{{#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() {
var gallery = new Gallery();
gallery.replaceBody('<img src="1.png" alt="" />\n<img src="2.png" alt="" />');
var modal = new Modal({
foo: 'bar',
name: this.user.fullName
});
modal.prependTitle('Image 1 - ');
modal.replaceBody('<img src="1.png" alt="" />');
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.
{{#block "header"}}
<h1>Hello World</h1>
{{/block}}
{{#block "main"}}
<p>Lorem ipsum...</p>
{{/block}}
{{#block "footer"}}
<p>© 1970</p>
{{/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:
<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>
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:
{{!-- layout.hbs --}}
<div class="grid">
<div class="grid-col {{#if (content "right")}}grid-col_2of3{{else}}grid-col_full{{/if}}">
{{{block "left"}}}
</div>
{{#if (content "right")}}
<div class="grid-col grid-col_1of3">
{{{block "right"}}}
</div>
{{/if}}
</div>
For a page that only needs a left column, you may omit defining content for the right
block:
{{!-- page.html --}}
{{#extend "layout"}}
{{#content "left"}}
<p>Left</p>
{{/content}}
{{/extend}}
Resulting in:
<div class="grid">
<div class="grid-col grid-col_full">
<p>Left</p>
</div>
</div>
For a page with two columns, simply define content for both blocks:
{{!-- page.html --}}
{{#extend "layout"}}
{{#content "left"}}
<p>Left</p>
{{/content}}
{{#content "right"}}
<p>Right</p>
{{/content}}
{{/extend}}
Resulting in:
<div class="grid">
<div class="grid-col grid-col_2of3">
<p>Left</p>
</div>
<div class="grid-col grid-col_1of3">
<p>Right</p>
</div>
</div>
<!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>
{{#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}}
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);
<!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>
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 me@shannonmoeller.com
Licensed under MIT
FAQs
Handlebars helpers which implement layout blocks similar to Jade, Jinja, Nunjucks, Swig, and Twig.
The npm package handlebars-layouts receives a total of 83,463 weekly downloads. As such, handlebars-layouts popularity was classified as popular.
We found that handlebars-layouts demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.
Security News
Research
Socket's threat research team has detected five malicious npm packages targeting Roblox developers, deploying malware to steal credentials and personal data.