Handlebars.js is a template framework for Javascript environments. It allows the construction of HTML elements using HTML and expressions wrapped in {{ }}
One of the conditional block helpers Handlebars offers is the {{#if}}
.
For example:
<div class="entry">
{{#if author}}
<h1>{{firstName}} {{lastName}}</h1>
{{else}}
<h1>Unknown Author</h1>
{{/if}}
</div>
Unfortunately, that's about all you can do with the if
out of the box. Luckily, Handlebars provides means of working with such expressions as well as adding your own. Using the registerHelper
method, we will change the if
block to support testing for property equality.
To do so, we will pass registerHelper
a modified version of the if
function where we utilize Handlebars' ability to parse key-value attributes in expressions:
Handlebars.registerHelper("if", function(conditional, options) {
if (options.hash.desired === options.hash.type) {
options.fn(this);
} else {
options.inverse(this);
}
});
Now, our modified if
expressions look something like this:
{{#if type desired="image" type=type}}
<div class="msg img">
<strong>{{user}}</strong> <i>shared an image</i>
<br />
<a href="{{file}}"><img src="{{file}}" /></a>
</div>
{{/if}}
where type
is a property of this
in our current scope, and "image"
is a possible value for type
.
Of course, you may want to define your own block expression instead of overriding the default {{#if}}
, but the idea holds.
tl;dr Comparison operators don't bloat templates with logic, more likely they will make both your templates and your javascript simpler.
Consider my use case: An admin portal with a page that displays information about a specific user. One panel on this page displays other users to which this user is somehow related. And now for the tricky part: The user that the page is displaying, he could be in that list himself. But he might not. Like an optional relationship to himself. And if he himself is in that list, we want to display some text. (Or maybe remove an href, because why would we link to the page we're already on?)
With
#if
defaulting to===
for two arguments, the template would be:While now I have to do:
With the second option now also requiring me to add
hasRelationToHimself
andrelatedUsersWithoutHimself
in my javascript somewhere else. This makes me a sad panda because more code = more bugs.This is solved with the 'compare' helper by Mike Griffin mentioned in a comment above:
But I would prefer an implementation of the
if
helper itself that takes either 1 (Boolean), 2 (Equality) or 3 (Anything) arguments.P.S. Here is Mike's code: