Luke Lee

Software Engineer

Web + Desktop + Science

Fork me on Github

Dealing with special characters in JSON and Handlebars.js templates

I recently had to dive in much deeper into Handlebars.js while working on a new feature to the nifty Syte project. Handlebars.js is just one of the many client-side Javascript templating languages available these days.

The project is relatively mature and pretty easy to work with. However, I ran into a weird problem with the template language itself and some of syntax/reserved characters. Handlebars.js reserves the '#' character for some of the block helpers.

These helpers are useful for handling small amounts of logic like if and loop statements. However, what happens when you are passing in a JSON context variable that uses '#' as a key?

Take the below snippet of JSON from a call to the last.fm API:

{
    "recenttracks": {
        "@attr": {
            "page": "1", 
            "perPage": "10", 
            "total": "54185", 
            "totalPages": "5419", 
            "user": "durden2.0"
        }, 
        "track": [
            {
                "album": {
                    "#text": "Shake! Shake! Shake!", 
                    "mbid": "03a8bcdb-112b-4d75-973a-2b727f1020ee"
                }, 
            }
    ]
}

Ideally in the template you would use something like this to render the '#text' information in html:

{{#with recenttracks }}
  
    {{#each track}}
  • {{album.#text}}
  • {{/each}}
{{/with}}

Unfortunately this will not work since '#' is reserved by the templating language itself.

I couldn't seem to find a good way to accomplish this without parsing all of the JSON myself just to make a new JSON object without '#' in the keys. This seems like a bunch of work so I went to the Internet for a solution.

I found a few interesting Github issues related to this topic:

Neither of these really had a solution, but I did stumble on a way to 'register helpers' using the Handlebars.registerHelper() functionality. This is similar to custom tags/filters in the Django world.

Essentially it allows you to specify a 'function' to pass the template variable through, which turns out to be a good way to temporarily 'bounce out' of the Handlebars.js templating language and back to standard Javascript code. Getting the requested variable out is easy with the normal syntax for associative arrays once your in standard Javascript code.

For example, here is the simple solution once all these pieces are put together:

I also posted this solution on the previously mentioned Github issue so be sure to go there and follow the on-going discussion.

Published: 07-07-2012 20:50:00

lukelee.net