3

I'm contemplating moving the tempating language of my express app from Jade to Handlbars, and I'm wondering if there is an equivalent to the Jade extend directive in handlebars.

user379468
  • 3,989
  • 10
  • 50
  • 68
  • Possible duplicate of [Extending Handlebars.js templates](http://stackoverflow.com/questions/22474194/extending-handlebars-js-templates) – br3w5 Oct 09 '15 at 16:25

2 Answers2

8

As i can see, in the repository of handlebars tells you that exist a dependencie for handlebars that can enable you to extends blocks. You can found more information here and here.

layout.hbs

<!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>&copy; 2013</small>
            {{/block}}
        </div>
    </div>

    {{#block "foot"}}
        <script src="assets/js/controllers/home.js"></script> 
    {{/block}}
</body>
</html>

Here we define a basic layout where you can extend others html from this one.

page.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}}

In this file you set all the data you want to extend from layout.

The .js file

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'
    ]
});

1. Require handlebars and handlebars-layout
2. Register the helper in the handlebar as a layout.
3. Register partials set the file layout.hbs as a "module" called 'layout', then in the page.html you set the extension from 'layout' 4. Compile in template the extension page.html.
5. Render template passing data from js to the file.

hjpotter92
  • 78,589
  • 36
  • 144
  • 183
Mateo Marconi
  • 614
  • 5
  • 16
  • 1
    when referring to external ressources you should always provide an example in order to create an acceptable answer. cheers. – GottZ Oct 09 '15 at 16:53
  • 1
    @GottZ Thanks, I copy and paste code from the resources i have posted but i explain a little of how this work. I wish this can help! – Mateo Marconi Oct 09 '15 at 19:01
0

For those looking for a webpack solution. I leave a snippet of code with my configuration:

webpack.config.js

...
const fs = require("fs")
const HandlebarsPlugin = require("handlebars-webpack-plugin")
const HandlebarsLayouts = require('handlebars-layouts');

module.exports = {
    ...,
    plugins: [
        ...,
        new HandlebarsPlugin({
            ...,
            onBeforeSetup: function(Handlebars){
                Handlebars.registerHelper(HandlebarsLayouts(Handlebars));
                Handlebars.registerPartial('default', fs.readFileSync('path/to/layout.hbs', 'utf8'));
            }
        })
    ]
}

References:

Handlebars Webpack Plugin

Handlebars Layouts