Skip to content

Instantly share code, notes, and snippets.

@pheuter
Created August 29, 2012 17:33
Show Gist options
  • Star 38 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save pheuter/3515945 to your computer and use it in GitHub Desktop.
Save pheuter/3515945 to your computer and use it in GitHub Desktop.
Handlebars.js equality check in #if conditional

Handlebars.js is a template framework for Javascript environments. It allows the construction of HTML elements using HTML and expressions wrapped in {{ }}

Limitations of {{if}}

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.

registerHelper

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.

@milpas999
Copy link

Hey, I am new to express and handlebars. I am aslo facing the same issue. I understand the above solution, but where to put Handlebars.registerHelper code.

@brundonsmith
Copy link

brundonsmith commented Sep 23, 2016

I generally consider myself to be fairly idealistic in my coding. But this is the first time overidealism in a software project has been so absurd as to make me genuinely angry. After converting most of my project from SWIG (now dead) to Handlebars, I'm now having to convert it all over to Nunjucks.

I made sure to check for "includes basic comparison operators out of the box" under the features section. I never thought I would be so excited to see that.

@minexew
Copy link

minexew commented Sep 23, 2016

@brundonsmith is not wrong

@silicahd
Copy link

Handlebars is a piece of s....t and I for one, completely refuse to use it and also divert anybody form ever using it. The first statement on this page sounds like a corporate bullcrap that you see everywhere. "Luckily, Handlebars provides means of working with such expressions". WAIT WHAT?????? the simplest operator comparison function in any langues was omitted but you allow me to add that functionality, by writing an extra 6 lines of code for every time I need this done. WOW thanks for such a privilege. DO YOURSELF A FAVOR AND DO NOT USE THIS TEMPLATING ENGINE. even JADE with its god awful white space fiasco is better than this turd. From the bottom of my heart. --virgil

@brennancheung
Copy link

I get not having business logic in the template, but having template logic in the template makes perfect sense. Like {{#if page === currentPage}}...{{/if}}. That doesn't belong in a controller or a helper. Having to make a helper for that situation is overkill and not the right place for it.

Also, adding a helper is only an option if you have control over everything. What about if you want to expose Handlebars as a templating engine for 3rd party users. You're not going to give random strangers full access to write whatever JS they want on your node server.

If you can't anticipate every helper a customer is going to need you are going to have a support nightmare and have to do new builds each time you add a helper.

I like the compare helper above.

If you just need === you can do:

Handlebars.registerHelper('ifeq', (a, b, options) => {
  if (a === b) {
    return options.fn(this)
  }
  return options.inverse(this)
})

You can implement them for ifneq, ifgt, ifgte, etc.

@rohitsharma00013
Copy link

Where has to put Handlebars.registerhelper)........ code ?

@NagatoPeinI1
Copy link

@thomasvanlankv I tried your method but it is giving me an error ::: result = operators[operator](lvalue, rvalue); is not a function.

@NagatoPeinI1
Copy link

Can anyone can explain how this handlebars.registerHelper are able to get the value for that function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment