Gathering detailed insights and metrics for handlebars-layouts
Gathering detailed insights and metrics for handlebars-layouts
Gathering detailed insights and metrics for handlebars-layouts
Gathering detailed insights and metrics for handlebars-layouts
Handlebars helpers which implement layout blocks similar to Jinja, Nunjucks (Swig), Pug (Jade), and Twig.
npm install handlebars-layouts
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
361 Stars
147 Commits
29 Forks
8 Watching
2 Branches
4 Contributors
Updated on 02 Nov 2024
JavaScript (68.64%)
HTML (31.36%)
Cumulative downloads
Total Downloads
Last day
-4.5%
17,860
Compared to previous day
Last week
-0.2%
105,089
Compared to previous week
Last month
-5.9%
466,364
Compared to previous month
Last year
-0.2%
6,686,131
Compared to previous year
handlebars-layouts
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.
layouts(handlebars) : Object
handlebars
Handlebars
- An instance of Handlebars.Generates an object containing the layout helpers suitible for passing into registerHelper
.
1var handlebars = require('handlebars'), 2 layouts = require('handlebars-layouts'); 3 4handlebars.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.
1var handlebars = require('handlebars'), 2 layouts = require('handlebars-layouts'); 3 4layouts.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.
1{{#extend "layout" foo="bar"}} 2 {{#content "title" mode="prepend"}}Example - {{/content}} 3{{/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:
1class Page extends Layout { 2 constructor() { 3 this.foo = 'bar'; 4 } 5 6 title() { 7 return 'Example - ' + super(); 8 } 9}
{{#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.
1{{#extend "layout"}} 2 3 {{#content "body"}} 4 {{#embed "gallery"}} 5 {{#content "body"}} 6 <img src="1.png" alt="" /> 7 <img src="2.png" alt="" /> 8 {{/content}} 9 {{/embed}} 10 11 {{#embed "modal" foo="bar" name=user.fullName}} 12 {{#content "title" mode="prepend"}}Image 1 - {{/content}} 13 {{#content "body"}}<img src="1.png" alt="" />{{/content}} 14 {{/embed}} 15 {{/content}} 16 17{{/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:
1class Page extends Layout {
2 body() {
3 var gallery = new Gallery();
4
5 gallery.replaceBody('<img src="1.png" alt="" />\n<img src="2.png" alt="" />');
6
7 var modal = new Modal({
8 foo: 'bar',
9 name: this.user.fullName
10 });
11
12 modal.prependTitle('Image 1 - ');
13 modal.replaceBody('<img src="1.png" alt="" />');
14
15 return gallery.toString() + modal.toString();
16 }
17}
{{#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.
1{{#block "header"}} 2 <h1>Hello World</h1> 3{{/block}} 4 5{{#block "main"}} 6 <p>Lorem ipsum...</p> 7{{/block}} 8 9{{#block "footer"}} 10 <p>© 1970</p> 11{{/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:
1<html> 2 ... 3 <body> 4 {{#block "header"}} 5 <h1>Hello World</h1> 6 {{/block}} 7 8 {{#block "main"}} 9 <p>Lorem ipsum.</p> 10 {{/block}} 11 12 {{#block "footer"}} 13 <p>© 1999</p> 14 {{/block}} 15 </body> 16</html>
Page:
1{{#extend "layout"}} 2 3 {{#content "header"}} 4 <h1>Goodnight Moon</h1> 5 {{/content}} 6 7 {{#content "main" mode="append"}} 8 <p>Dolor sit amet.</p> 9 {{/content}} 10 11 {{#content "footer" mode="prepend"}} 12 <p>MIT License</p> 13 {{/content}} 14 15{{/extend}}
Output:
1<html> 2 ... 3 <body> 4 <h1>Goodnight Moon</h1> 5 6 <p>Lorem ipsum.</p> 7 <p>Dolor sit amet.</p> 8 9 <p>MIT License</p> 10 <p>© 1999</p> 11 </body> 12</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:
1{{!-- layout.hbs --}} 2<div class="grid"> 3 <div class="grid-col {{#if (content "right")}}grid-col_2of3{{else}}grid-col_full{{/if}}"> 4 {{{block "left"}}} 5 </div> 6 {{#if (content "right")}} 7 <div class="grid-col grid-col_1of3"> 8 {{{block "right"}}} 9 </div> 10 {{/if}} 11</div>
For a page that only needs a left column, you may omit defining content for the right
block:
1{{!-- page.html --}} 2{{#extend "layout"}} 3 4 {{#content "left"}} 5 <p>Left</p> 6 {{/content}} 7 8{{/extend}}
Resulting in:
1<div class="grid"> 2 <div class="grid-col grid-col_full"> 3 <p>Left</p> 4 </div> 5</div>
For a page with two columns, simply define content for both blocks:
1{{!-- page.html --}} 2{{#extend "layout"}} 3 4 {{#content "left"}} 5 <p>Left</p> 6 {{/content}} 7 8 {{#content "right"}} 9 <p>Right</p> 10 {{/content}} 11 12{{/extend}}
Resulting in:
1<div class="grid"> 2 <div class="grid-col grid-col_2of3"> 3 <p>Left</p> 4 </div> 5 <div class="grid-col grid-col_1of3"> 6 <p>Right</p> 7 </div> 8</div>
1<!doctype html> 2<html lang="en-us"> 3<head> 4 {{#block "head"}} 5 <title>{{title}}</title> 6 7 <link rel="stylesheet" href="assets/css/screen.css" /> 8 {{/block}} 9</head> 10<body> 11 <div class="site"> 12 <div class="site-hd" role="banner"> 13 {{#block "header"}} 14 <h1>{{title}}</h1> 15 {{/block}} 16 </div> 17 18 <div class="site-bd" role="main"> 19 {{#block "body"}} 20 <h2>Hello World</h2> 21 {{/block}} 22 </div> 23 24 <div class="site-ft" role="contentinfo"> 25 {{#block "footer"}} 26 <small>© 2013</small> 27 {{/block}} 28 </div> 29 </div> 30 31 {{#block "foot"}} 32 <script src="assets/js/controllers/home.js"></script> 33 {{/block}} 34</body> 35</html>
1{{#extend "layout"}} 2 {{#content "head" mode="append"}} 3 <link rel="stylesheet" href="assets/css/home.css" /> 4 {{/content}} 5 6 {{#content "body"}} 7 <h2>Welcome Home</h2> 8 9 <ul> 10 {{#items}} 11 <li>{{.}}</li> 12 {{/items}} 13 </ul> 14 {{/content}} 15 16 {{#content "foot" mode="prepend"}} 17 <script src="assets/js/analytics.js"></script> 18 {{/content}} 19{{/extend}}
1var handlebars = require('handlebars'); 2var layouts = require('handlebars-layouts'); 3 4// Register helpers 5handlebars.registerHelper(layouts(handlebars)); 6 7// Register partials 8handlebars.registerPartial('layout', fs.readFileSync('layout.hbs', 'utf8')); 9 10// Compile template 11var template = handlebars.compile(fs.readFileSync('page.html', 'utf8')); 12 13// Render template 14var output = template({ 15 title: 'Layout Test', 16 items: [ 17 'apple', 18 'orange', 19 'banana' 20 ] 21}); 22 23console.log(output);
1<!doctype html> 2<html lang="en-us"> 3<head> 4 <title>Layout Test</title> 5 6 <link rel="stylesheet" href="assets/css/screen.css" /> 7 <link rel="stylesheet" href="assets/css/home.css" /> 8</head> 9<body> 10 <div class="site"> 11 <div class="site-hd" role="banner"> 12 <h1>Layout Test</h1> 13 </div> 14 15 <div class="site-bd" role="main"> 16 <h2>Welcome Home</h2> 17 <ul> 18 <li>apple</li> 19 <li>orange</li> 20 <li>banana</li> 21 </ul> 22 </div> 23 24 <div class="site-ft" role="contentinfo"> 25 <small>© 2013</small> 26 </div> 27 </div> 28 29 <script src="assets/js/analytics.js"></script> 30 <script src="assets/js/controllers/home.js"></script> 31</body> 32</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
MIT © Shannon Moeller
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
0 existing vulnerabilities detected
Reason
license file detected
Details
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
Found 2/27 approved changesets -- score normalized to 0
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
project is not fuzzed
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
security policy file not detected
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Score
Last Scanned on 2024-11-18
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More