Search code examples
javascripthandlebars.js

Handlebars Include partial twice, once escaped and once rendered


I have a handlebars partial that I want to include twice on my page. Once as normal HTML to be parsed and displayed, and once as escaped HTML to be shown to the user (kind of like on the Bootstrap docs as shown in the image below):

enter image description here

In underscore templates it would just be:

    {% examples/buttons %}
    <code>
        {%- examples/buttons %}
    </code>

How can I accomplish it in Handlebars?

I'm rendering these files on a node.js server and using the built-in partials feature (this doesn't work. I can't figure out what to make the second one look like to tell it to escape the HTML):

    {{> examples/buttons }}
    <code>
        {{> examples/buttons }}
    </code>

Solution

  • This can be done with a custom block helper:

    // [this is in /lib/hbs-helpers.js file]
    exports.escapedPartial = function (partials, partialName, data) {
         return partials[partialName](data.hash);
    };
    

    Registered with express-handlebars:

    // [this is in js file which starts the express app, probably app.js]
    var expressHandlebars       = require( 'express-handlebars' );
    var handlebarsHelpers       = require('./lib/hbs-helpers');
    
    var hbs = expressHandlebars.create({
        defaultLayout: 'master',
        extname: ".hbs",
        helpers: handlebarsHelpers,
        partialsDir: "views/partials"
    });
    
    // Configuring view engine
    app.engine('.hbs', hbs.engine);
    app.set('view engine', '.hbs');
    

    And finally used from within the handlebars template itself (in some hbs file like, button-docs.hbs). @exphbs.partials must be passed through so that the helper has access to the partials (there is probably another better way for it to access this global, but, I don't know it):

        {{> examples/buttons foo="bar"}}
            <code>
    {{escapedPartial @exphbs.partials "examples/buttons" foo="bar"}}
            </code>