5

A project I'm working on uses Handlebars.js template system. It reads in content and when compiling the template injects the content where appropriate:

<div class="content">
  <p>lorem ipsum</p>

  {{{ content }}}

</div>

In this case the handlebars is compiled with a JS object who has a content property that is a string of text or HTML (hence the triple brackets).

However it is entirely possible that the content value (being text or HTML) could also include handlebars interpolation code:

var contentPassedToHandlebars = {
  content: '<p>{{ foobar }}</p>',
  foobar: 'foo'
};

Which currently outputs <p>{{ foobar }}</p> but what I would intend to get is <p>foo</p>.

Does handlebars have a facility for this nested content or is a custom helper required? ({{{custom_parse content}}})?

For context to this question

The situation derived from a build system (metalsmith) that reads in files as markdown, converted them to HTML, attach result to the content property of the file object, then parse a handlebars template which injects the file.content into it output. All this and I was hoping there was a solution to place handlebars or string interpolation into the markdown so the markdown files could have access to the same variables the templates have access to (obviously more global values in a config.json not the values associated with the file object being constructed).

Sukima
  • 9,965
  • 3
  • 46
  • 60
  • AFAIK handlebars does not have such kind of facilities. Also, it'd be hard to implement this using helpers too, even if you do, it does not look like best approach. I think you should try RegExping your root template first, and replace all "{{{ VAR_NAME }}}" sequences first, only then compile the result. – Jevgeni Oct 02 '14 at 14:35

2 Answers2

4

There is no built in way to do this. You would have to manage you own pre-rendering process or internal helper.

For the solution I ended up running a pre-render before the official render. Although the code is not handlebars but instead part of the metalsmith-templates plugin, here is the solution I used.

This roughly translated to:

var contentPassedToHandlebars = {
  content: '<p>{{ foobar }}</p>',
  foobar: 'foo'
};

var x = Handlebars.compile(contentPassedToHandlebars.content)(contentPassedToHandlebars);
contentPassedToHandlebars.content = x;

Handlebars.compile(realTemplateSource)(contentPassedToHandlebars);
Sukima
  • 9,965
  • 3
  • 46
  • 60
1

OR use this:

metalsmith-in-place

```
index.js
var inPlace = require('metalsmith-in-place')

....
.use(inPlace(true))
.....

Now, if you write {{> footer }} it will do the work.

Gaurav Kumar
  • 55
  • 15