Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I load different partials dynamically using handlebars templates?

I'm loading a template with the following data:

"slides": [
    {
        "template": "video",
        "data": {
            "video": ""
        }
    },
    {
        "template": "image",
        "data": {
            "image": ""
        }
     }
]

in my template I want to loop over these slides and based on the configured template I want to load a partial

{{#each slides}}
    {{> resources_templates_overlay_video }}
{{/each}}

How can I make this partial load dynamically (based on the configured template)?

I'm using the require-handlebars-plugin

like image 870
Daan Poron Avatar asked Nov 15 '12 11:11

Daan Poron


People also ask

Why would we use partials in a Handlebars template?

Handlebars Partials Partials are useful when you have a chunk of markup that you want to reuse in more than one place. A Handlebars partial is just a template that you can render inside of another template using the {{> partialName }} partial call syntax after registering it with Handlebars.

Where do I register my Handlebars partials?

In order to use a partial, it must be registered via Handlebars. registerPartial . Handlebars. registerPartial('myPartial', '{{prefix}}');


1 Answers

As far as I can tell, hbs expects the partials to be known at compile time, which is way before you pass in your data. Let's work around that.

First, pull in your dynamic partials before rendering, something like:

// I required the main template here for simplicity, but it can be anywhere
var templates = ['hbs!resources/templates/maintemplate'], l = data.slides.length;
for (var i=0; i<l; i++ )
    templates.push('hbs!resources/templates/overlay/'+data[i].template);

require(templates, function(template) {
    var html = template(data);
});

And define a helper that will act as a dynamic partial

define(['Handlebars'], function (Handlebars) {

    function dynamictemplate(template, context, opts) {
        template = template.replace(/\//g, '_');
        var f = Handlebars.partials[template];
        if (!f) {
            return "Partial not loaded";
        }

        return new Handlebars.SafeString(f(context));
    }

    Handlebars.registerHelper('dynamictemplate', dynamictemplate);
    return dynamictemplate;
});

Finally, modify your main template to look like

{{#each slides}}
    {{dynamictemplate this.template this.data}}
{{/each}}
like image 174
nikoshr Avatar answered Sep 21 '22 18:09

nikoshr