How to render partials/helpers *inside* a string variable?

966 Views Asked by At

Say I've got the following template/scenario:

{{partial-container container}}

{{{content.html}}}

{{#each content.partials}}
  {{this}} // <-- here I'd like to render partials that users requested.
{{/each}}

Goals

  • [Done] I want to render a block of text, html-escaped, using the html property.
  • From the JSON, we also get a list of "partials" to render, but I can't figure out how to make this work.

Ideally, the syntax would be something like this:

{{partial-container container}}

{{{content.html}}}

{{#each content.partials}}
  {{ > {{this}} }}
{{/each}}

But that throws a syntax error. Is there any way to interpret the contents of a variable as the name for a partial to render (and do so)?

1

There are 1 best solutions below

0
On BEST ANSWER

I am assuming that your "list of partials" is an array of names matching with registered partials. Something like:

"partials": ["fooPartial", "barPartial", "fooPartial"]

The Handlebars documentation states that partials can be dynamically selected using a subexpression, but this subexpression must be a function that returns the partial name. This means that something as simple as {{> (this)}} will not work because our this is the string value of our partial name and not a function.

I see two ways of achieving our goal.

Option 1: Map the partial names to functions

If we have the ability to modify the data we are sending to our template, we could map the partial names into functions that return the name:

"partials": ["fooPartial", "barPartial", "fooPartial"].map(partialName => () => partialName)

These functions would allow us to dynamically insert our partials into our template with {{> (this)}}.

See this fiddle for an example.

Option 2: Use the lookup helper

If modifying our input data is not an option, we can use the Handlebars built-in lookup helper. The trick here is that, within our #each loop, we must step-up a context-level to get our partials array and then use the @index helper variable to get the partial name at the current index. The template would become:

{{#each content.partials}}
  {{> (lookup ../content.partials @index)}}
{{/each}}

See this fiddle for an example.