Using Layout, Partials with Handlebars Template
Asked Answered
S

2

8

How do I use layouts, partials with handlebars template like the following?

I have looked at the partial docs but still could not figure out what I wanted to achieve.

default.html

The default layout is reused for the different views of the site. {{{content}}} is used as a placeholder for where the main content will be rendered.

<!DOCTYPE html>
<html>
<head>  
  <title>{{title}}</title>
</head>
<body>
 <p>This is the top of the body content in the default.html file</p>
 {{{content}}}
 <p>This is the bottom of the body content in the default.html file</p>
</body>
</html>

index.html

{{#> default}}

{{ include header }}
<p>This is some other content</p>
{{ include footer }}

header.html

<h1>This is a header</h1>

footer.html

<p>This is a footer</p>

Output

<!DOCTYPE html>
<html>
<head>  
  <title>Using Layout, Partials with Handlebars Template</title>
</head>
<body>
 <p>This is the top of the body content in the default.html file</p>
 <h1>This is a header</h1>
 <p>This is some other content</p>
 <p>This is a footer</p>
 <p>This is the bottom of the body content in the default.html file</p>
</body>
</html>
Soubriquet answered 23/9, 2016 at 9:43 Comment(2)
Check the docs handlebarsjs.com/partials.htmlLetsou
@AndreyEtumyan. I have updated my question.Soubriquet
J
3
  • First to make the partial work first remove the sharp(#) in front of your partial call in index.html.

    {{> default}}

  • Second : you won't be able to build a whole page (with headers) using handlebars : the javascript is loaded once the page has been loaded so headers are already sent and can't be modified. Handlebars.js is only useful if you want to manipulate the DOM to put your template result in a container.

You have an example of what can be done here: https://jsfiddle.net/ChristopheThiry/zepk5ebh/4/

<script id="default" type="text/x-handlebars-template">
 <p>This is the top of the body content in the default.html file</p>
 {{{content}}}
 <p>This is the bottom of the body content in the default.html file</p>
</script>

<script id="index" type="text/x-handlebars-template">
{{include header }}
{{> default}}
{{include footer }}
</script>

<div id="resultPlaceholder">
</div>

$(document).ready(function () {
  var defaultSource   = $("#default").html();
  var indexSource = $("#index").html();
  Handlebars.registerPartial('default',defaultSource);
  Handlebars.registerHelper('include', function(source) {
        return new Handlebars.SafeString(source);
});
  var template = Handlebars.compile(indexSource);
  var context = { "content" : "<b>This is some other content</b>","header" : "<h1>This is a header</h1>", "footer" : "<div class='footer'>This is a footer</div>"} ;
  var html    = template(context);
  $("#resultPlaceholder").html(html);
});

I hope the example will help ...

Jahncke answered 26/9, 2016 at 9:10 Comment(3)
Adding the partial {{> default}}, just includes the contents of the default.html file in its place. The result I get by doing what you said is shown in this gist, which is not what I want. See my updated question.Soubriquet
If it calls default.html then you call the partial... what is wrong here ? What result do you expect ? As far as I see you get the exact result that I expect from your call.Jahncke
The bottom of the body content appears first since the default.html is called first then the content of the partials appears. ie the header & the footer comes after the bottom of the body content which is incorrect.Soubriquet
V
2

I know that this question is outdated however, I've faced the same "problem" currently.

If you're with some doubts about the implementation, check it out the documentation.

An implementation example:

JS code

import * as Handlebars from 'handlebars';
import * as path from 'path';

...

const partial_path = path.join(HBS, partial);
const { name } = path.parse(path.basename(partial_path));
Handlebars.registerPartial(name, readHbs(partial_path)); // readHBS only reads the file syncronously.

Handlebars partial (base file)

<!DOCTYPE html>
<html lang="pt-br">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>title</title>
    <style>
    </style>
  </head>
  <body>
    <main class="flexbox">
      <div class="flexbox container paper">{{> @partial-block }}</div>
    </main>
  </body>
</html>

Handlebars template

{{#> base extra_headers="" }}
<header style="width: inherit;">
  <h1 style="text-align: center;"> I'm your template 😊</h1>
</header>
{{/base }}
Vachil answered 17/7, 2021 at 16:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.