Using Handlebars Templates in the SmartFile Application

The SmartFile application hits the same api you would hit, with your language of choice, for all the back-end work. That’s right, we eat our own dog food. On the front end, the application uses JavaScript for nearly everything. Using JavaScript so heavily presented a unique challenge when it came to rendering html. Some of the places html is rendered include the sidebars, dialogs, and the activity filter accordion.

Initially when I came on-board at SmartFile, arrays of strings were used to render the html.

var html = [];
html.push ('<div>', gettext('Some words in the div'), '</div>');
html.join(''); //render

You can take something like that and spread it over multiple lines and it’s still hard to read. Now, imagine throwing in some attributes on the div such as title=”Tooltip” or style=”font-weight: bold;”. It gets harder and harder to read.

Ben Timby realized this was a challenge. He devised a solution to use a jQuery plugin to chain all the html together and make it look more like the JavaScript. He came to me one day, “You gotta try this jQuery plugin.” So I tried the plugin:

var html = chains.div().text(gettext('Some words in the div'));

From a jQuery standpoint, this makes perfect sense and this example is fairly easy to read. But, it falls victim to similar problems as the above solution. When you want to add attributes you add them as an object, but it gets hard to read quickly:

var html = chains.div({'title' : 'Tooltip', 'style' : 'font-weight' : 'bold'}).text(gettext('Some words in the div'));

So, Ben Timby continues to worry about this and comes to me one day with handlebars. Boom. Now this is a neat concept. You create a template that is very similar to our django templates and pass it a context just like our django templates:

<div>{{ trans 'Some words in the div' }}</div>

In the above example, I had to create a trans helper and we had to add a step to our build process to find these and parse them out to ensure they are translated. Handlebars now feels like a much better solution. I can add ifs and context variables into the template.

We tend to use the same dialog for creating and editing. So for a link create/edit form, I can add something like value=”{{ link.href }}” and if link is undefined, it will ignore it. The great part about this is that in a single step I can render the template and merge in data. This removes the need for rendering, then later injecting data using jQuery.

Recently I worked on converting all the chains to handlebars and it’s now our main solution for client side templates. Now don’t get me wrong, there is still a place for inline html. It is usually reserved for 1-2 lines of html that would add a ton of overhead as a handlebars template. Inline html is also great for complex logic situations where html is dynamically generated and JavaScript events are attached in one loop rather than looping through it in the template and looping through it again to add events.

SmartFile is a business file mangement platform that gives you more control, compliance and security.