Search code examples
character-encodingescapinghandlebars.jsbackground-image

Forward slashes in input object do not render in Handlebars #each partial


When trying to render a Handlebars partial, all the forward slashes in my object render as spaces instead.

My input object is like this:

let mySkills = {
    "skills": [
        {
            "name": "HTML5",
            "icon": "/img/HTML5.png"
        },
        {
            "name": "CSS3",
            "icon": "/img/CSS3.png"
        },
        {
            "name": "JavaScript",
            "icon": "/img/JS.png"
        }
    ]
};

The Handlebars partial is like this (I simplified it for this post. I know it won't look right, but the point is that the output code is incorrect):

Handlebars.registerPartial(
    'skillsBullet',
    '<ul>{{#each skills}}<li style="background-image: url("{{icon}}");">{{name}}</li>{{/each}}</ul>'
);
$('#skills-container').append(Handlebars.compile($('#skills-template').html())(mySkills));

But the output snippet is like this: Broken background image url

Here is a Codepen. You can inspect the Elements panel to see the bug in the above screenshot: https://codepen.io/car1sle/pen/NWYJeee

I already tried:

  • Putting backslashes before the forward slashes in the object like this "icon": "\/img\/HTML5.png"
  • Doing triple curly braces in the Partial like this {{{icon}}}
  • Doing regular brackets inside the braces in the Partial like this {{[icon]}}

Solution

  • Your issue is due to the fact that your resultant HTML is malformed.

    Let's examine this piece of your partial:

    <li style="background-image: url("{{icon}}");">
    

    You are using double-quotes (") to wrap both the style= value and the url() value. After Handlebars processing, the resultant HTML becomes:

    <li style="background-image: url("/img/CSS3.png");">
    

    This HTML instructs the browser that the style value - between the two double-quotes - is background-image: url(. The browser then tries to determine what to do with the /img/CSS3.png");" and it, because browsers are forgiving of malformed HTML, it ignores it and carries on.

    In order to get your code to work properly, you will need to use different quotes for the background-image URL than you use for the style attribute.

    <li style="background-image: url(\'{{icon}}\');">
    

    I have forked for your Codepen to provide an example.