Comparison block helper for handlebars templates

I really like the handlebars template system, it’s straight to the point, efficient, and the added logic layer to mustache makes it practical for most scenarios.

One limitation i’ve found was that if block helpers can’t actually evaluate an expression, it only tests if the passed value is already true or false, there’s no evaluation of it.

so this:

{{#if unicorns == ponies }}
That's amazing, unicorns are actually undercover ponies
{{/if}}

doesn’t work, bummer.

I initially needed to do just that (the == bit, not the unicorns & ponies assertion) so I wrote a basic block helper that checks if two values are equal.

This is done quite simply like this:

Handlebars.registerHelper('equal', function(lvalue, rvalue, options) {
    if (arguments.length < 3)
        throw new Error("Handlebars Helper equal needs 2 parameters");
    if( lvalue!=rvalue ) {
        return options.inverse(this);
    } else {
        return options.fn(this);
    }
});

You can then rewrite the handlebar template code above as:

{{#equal unicorns ponies }}
That's amazing, unicorns are actually undercover ponies
{{/equal}}

Then I thought, what if I want to check if the unicorns are bigger than the ponies, or if the ponies and unicorns are the same type.. ?

You could easily write a helper for each comparison operator but that would be a bit long.

Handlebars allows you to pass extra named attributes called hashed arguments to the block helper. These can then be retrieved inside the helper through the options.hash attributes.

So I made the equal helper a more generic compare helper. It still takes 2 parameters, but you can also pass an optional operator hashed argument. If you omit the operator argument it default to ==.

Here’s the full code:

Handlebars.registerHelper('compare', function(lvalue, rvalue, options) {

    if (arguments.length < 3)
        throw new Error("Handlerbars Helper 'compare' needs 2 parameters");

    var operator = options.hash.operator || "==";

    var operators = {
        '==':       function(l,r) { return l == r; },
        '===':      function(l,r) { return l === r; },
        '!=':       function(l,r) { return l != r; },
        '<':        function(l,r) { return l < r; },
        '>':        function(l,r) { return l > r; },
        '<=':       function(l,r) { return l <= r; },
        '>=':       function(l,r) { return l >= r; },
        'typeof':   function(l,r) { return typeof l == r; }
    }

    if (!operators[operator])
        throw new Error("Handlerbars Helper 'compare' doesn't know the operator "+operator);

    var result = operators[operator](lvalue,rvalue);

    if( result ) {
        return options.fn(this);
    } else {
        return options.inverse(this);
    }

});

Gist

And now you can do this:

{{#compare unicorns ponies operator="<"}}
I knew it, unicorns are just low-quality ponies!
{{/compare}}

Have fun!

Edit: Thanks to paul for pointing out in the comments section the misuse of the helper syntax, it should have been a block helper starting with a #.

Edit 2: Mike Griffin has a nice alternative version of this in the comments

License: Licensed under MIT License

71 comments on “Comparison block helper for handlebars templates

  1. Ognian Marinov

    Thanks! Saved me a lot of time.

    Reply
  2. trans

    Just goes to show that the “logicless views” concept is tragically misunderstood concept that has been taken to the extreme.

    Truth is, there are two different types of logic, “view logic” and “data logic”. Yes, you want to keep “data logic” out of your views. But “view logic” –which is logic that simply determines rendering by querying the data, is perfectly sensible.

    Your workaround for handlebars is case in point.

    Reply
  3. Matt Babineau

    I just tried to implement this helper, but it seems to be failing for me. Do I need to place it anywhere special in the code for Handlebars to register it?

    Reply
    1. bendog

      Hey Matt,

      You should register the helper after Handlebars is loaded and before you use it in a template.

      What do you mean by “failing”? not working at all, or not comparing properly.

      Check your javascript error log maybe, there might be some clues as to why it’s failing.

      Otherwise, write back with some relevant code you have…

      Reply
    2. paul

      Matt,

      you might just be missing the hash character when calling the compare function.

      {{#compare unicorns ponies operator=”<“}} I knew it, unicorns are just low-quality ponies! {{/compare}}

      Reply
      1. bendog

        @paul.

        No you don’t need the hash for these helpers.

        {{#compare}} and {{compare}} calls the helper with different arguments. If you use the hash “block helper” mode the functions won’t work as-is (afaik)

        I take that back, there definitely should be a #

        Reply
  4. paul

    bendog,

    Oh ok – sorry i only started using handlebars yesterday. Could you pls tell me what the main difference is between {{#compare}} and {{compare}}..

    Contrary to the doco, my experience has been that {{compare}} will evaluate the expression and {{#compare}} calls a helper function?

    I haven’t been able to find a good practical definition – even on thinkvitamin, handlebarjs etc tx paul

    Reply
    1. bendog

      @paul..

      actually, no you’re right.. should be #compare.. my mistake.

      The # syntax is a block helper, which means it can take an inner context (which must be closed with / )

      So you’ll have either:

      {{somehelper someparam}}

      or

      {{#someblockhelper someparam}} Some inner content {{/someblock_helper}}

      I’ll amend the copy now, thanks for pointing out the mistake in the copy :)

      Reply
  5. Mike Griffin

    Here’s a way that’s more readable … (I think anyway)

    Look how the syntax reads …

    =====================================

    
    {{#compare Database.Tables.Count ">" 5}}
    There are more than 5 tables
    {{/compare}}
    

    
    {{#compare "Test" "Test"}}
    Default comparison of "==="
    {{/compare}}
    

    =====================================

    
    Handlebars.registerHelper('compare', function (lvalue, operator, rvalue, options) {
    
        var operators, result;
        
        if (arguments.length < 3) {
            throw new Error("Handlerbars Helper 'compare' needs 2 parameters");
        }
        
        if (options === undefined) {
            options = rvalue;
            rvalue = operator;
            operator = "===";
        }
        
        operators = {
            '==': function (l, r) { return l == r; },
            '===': function (l, r) { return l === r; },
            '!=': function (l, r) { return l != r; },
            '!==': function (l, r) { return l !== r; },
            '<': function (l, r) { return l < r; },
            '>': function (l, r) { return l > r; },
            '<=': function (l, r) { return l <= r; },
            '>=': function (l, r) { return l >= r; },
            'typeof': function (l, r) { return typeof l == r; }
        };
        
        if (!operators[operator]) {
            throw new Error("Handlerbars Helper 'compare' doesn't know the operator " + operator);
        }
        
        result = operators[operator](lvalue, rvalue);
        
        if (result) {
            return options.fn(this);
        } else {
            return options.inverse(this);
        }
    
    });
    
    Reply
    1. bendog

      Hi Mike,

      That is nice indeed. Makes sense to have the operator in-between.

      Thanks for your contribution.

      Reply
    2. bendog

      I’ve edited the post entry to point readers to your version.

      Reply
    3. Michael Scepaniak

      Thank you very much for sharing this! It surprised me that such comparisons aren’t supported by Handlebars out of the box.

      Mike….

      Reply
    4. John

      Where should I place this piece of code in my app? In app.js (and thus the operators are shared across all views?)? Or the view itself where I want to use the operator?

      Reply
      1. bendog

        Hi John,

        Not hugely familiar with emberjs (assuming this is what you’re using) but you should only need to register the helper once, so it makes more sense to do it in your app.js application boot file rather than the view.

        A quick search returns a few SO answers that use app.js to do it (E.g. http://stackoverflow.com/questions/15769096/defining-a-block-helper-with-handlebars).

        Reply
        1. John

          Hi Ben,

          Nope, not ember, just express… I’m a complete n00b with node :-)

          For the clueless like me… place this in your app.js or server.js root file…

          // set handlebars as the templating engine :-} app.set(‘view engine’, ‘hbs’); app.set(‘views’, __dirname + ‘/app/views’);

          // hbs.handlebars is the handlebars module hbs.handlebars === require(‘handlebars’);

          // register handlebars helpers ============

          hbs.registerHelper(‘compare’, function (lvalue, operator, rvalue, options) {

          (( continue with Mike’s code above ))

          Reply
  6. Arun

    Hi ,

    I think there is an issue with this helper

    Handlebars.registerHelper('compare', function(lvalue, rvalue, options) {

    This considers lvalue and rvalue as strings. It does not evaluate the expression.For example This fails to compile. {{#compare 5 6 operator="=="}}Check equality{{/compare}} The above one throws an error saying “Object 2 has no method replace”

    But this works {{#compare "5" "6" operator="=="}}Check equality{{/compare}}

    Reply
    1. bendog

      Hi Arun,

      Thanks. That’s a fair remark. Haven’t had a chance to test this but I trust you’re correct.

      Actually, I just tried and I don’t seem to get the same problem.

      Here’s a test js fiddle that works as expected.

      Which browser are your testing this in?

      Maybe try to reduce your code to a limited test example to see if it works for you. If it does then maybe the problem is elsewhere.. ?

      Interested to know your feedback.

      Reply
      1. bendog

        Seems to works on latest Chrome, Firefox & IE 7 to 9

        Reply
      2. Justin Burris

        I’m seeing the same issue in Chrome 21. I’m using Handlebars 1.0.0.beta.6.js with ember.

        Perhaps it’s a similar issue for Arun as well?

        Reply
        1. bendog

          Hi Justin,

          Thanks for your input..

          Seems to work for me in Chrome 21 with 1.0 beta 6.

          Does the test jsfiddle fail for you? (http://jsfiddle.net/bendog/3N64P/)

          I haven’t tried it with ember – maybe it is something ember does, different way to compile templates maybe?

          Reply
  7. Matías

    And what about using compare with “Else” block??

    {{compare a b}} A and B are equal {{else}} Not equal {{/compare}} ??

    Reply
    1. bendog

      Hi Matías

      That should work fine.

      The helper uses an inverse, which is what the {{else}} triggers

      
      if( result ) {
            return options.fn(this);
      } else {
              return options.inverse(this);
      }
      
      

      You can also use {{^}} which does the same thing as else.

      Reply
  8. nauce

    Awesome helper. This is useful for SO many use cases!

    Reply
  9. Tarun

    how to compare numeric value , i am facing hard time comparing the following:

    {{#compare GroupType ABC.Constants.DashboardGroupType.UserDefinedGroup}}

    Where GroupType value is coming from Model and UserDefinedGroup value is coming from javascript variable.

    as soon as I change the statement to {{#compare GroupType 1}} it starts working. Seems to be an issue while fetching value from javascript file. Please help!!!

    Reply
    1. bendog

      Hi Tarun,

      (Sorry for the late comment approval, hadn’t checked in a while).

      I’m assuming you’ve checked that ABC.Constants.DashboardGroupType.UserDefinedGroup is actually set to a correct value. Right? :)

      The default operator is === which is strict equality, which means it won’t work if one of your operand is a number and the other one a string.. maybe that’s the problem here?

      If that’s the case, you should either change your variables type or use the == operator, which is more permisible..

      Reply
  10. Arnogues

    For a condensed version of operators :

    var operators = new Function("return {"+ "==,===,!=,!==,<,>,<=,>=" .replace(/([^,]+)/g, "'$1': function (l, r) { return l $1 r; }\n")+ ",'typeof': function (l, r) { return typeof l == r; } }")();

    Reply
    1. bendog

      Ah yeah, I guess, if your into that kind of things :)

      I’m not sure if it would be that much more efficient though..

      Reply
  11. Shameer

    Hi,

    This doesn’t seem to work inside a requirejs wired template file. I get the same problem as Arun reported – it doesnt evaluate the variable expressions.

    I have something like..

    
    {{#compare messageType "==" "Info"}}
    
            <a href="#" rel="nofollow">&times;</a>
            {{message}}
    
    {{/compare}}
    

    The lvalue I am getting inside the function is – “messageType”, instead of its actual value. I printed the expression outside the block, it shows the proper value.

    Reply
    1. bendog

      Hi Shameer,

      I haven’t tried it with requirejs. Maybe there is some sort of escaping going on when it’s compiled?

      Also, your example syntax looks incorrect, it should be something like:

      
      

      {{#compare messageType "Info" operator="=="}} ... {{/compare}}

      Hope this helps

      Reply
  12. Trki

    I dont know why but i always see in console this:

    Exception from Deps recompute: Error: Handlerbars Helper ‘compare’ needs 2 parameters

    I put the code in /client/helpers/handlebars.js… where should it go?

    Reply
    1. bendog

      Sounds like it’s detected properly but you may be using it wrong. That errors comes from the helper’s check at the beginning. You might be missing an argument in your template code.

      Can you post an example of how you’re using it?

      Reply
  13. Meph

    Hi, that looks nice, but I have a problem with implementation to ember. I have:

    {{#each controller}} {{id}} {{#compare id 3 operator=”==”}}Active{{else}}Error{{/compare}} {{/each}}

    I can’t set lvalue from id parametr of controller content. Does anyone help me?

    Reply
  14. David Baughman

    So good! Thanks for sharing this! I found another set of handlebars helpers, but they didn’t have any documentation on how to use them, so I got stuck. This one works like a charm!

    Reply
  15. Peter Drinnan

    Ah! thanks so much. I was going in circles looking at all kinds of “complex” solutions for such a seemingly simple problem.

    Reply
  16. Tim

    Awesome helper, but you may want to move

    var operators = { ... }
    

    part out of the helper, for performance reasons, so it would be something like

    var operators = {
        ...
    };
    
    Handlebars.registerHelper('compare', ... )
    
    Reply
    1. bendog

      Thanks Tim.

      Yes, this could be a fine micro optimisation – I was just trying to self-contain everything to minimise problems.

      Reply
  17. Aziz

    if you want to write anything you want in the IF expression, see this gist

    
    {{#xif " this.name == \"Sam\" && this.age === \"12\" " }}
      BOOM
    {{else}}
      BAMM
    {{/xif}}
    
    

    Here’s a demo: http://jsbin.com/jeqesisa/7/

    Reply
    1. bendog

      Thanks Aziz.

      I’ve merged your two comments.

      Should definitely highlight one of the comments in your gist: you NEED to properly escape the string literals

      Reply
  18. Mamshad K

    Hy guys, can anybody explain how to compare the dynamic strings using above helper Eample: {{#compare {{data}} test operator=”===”}} gives error where data comes from the list dynamicaaly

    {{#compare test test operator=”===”}} works as desired

    Thanks for the help in advance

    Reply
  19. Jeevi

    The values passed from the model is not passed to the custom helpers. From the each helper I am calling the ifCond registered helper.

    
        <ul>
        {{#each item in model}}
            {{#ifCond item '==' 'red'}}
                
  20. {{item}}
  21. {{/ifCond}} {{/each}} </ul>

    
    
    App.IndexRoute = Ember.Route.extend({
        model: function() {
            return ['red', 'yellow', 'blue', 'red', 'blue', 'pink'];
        }
    });
    
    
    
    
    
    Handlebars.registerHelper('ifCond', function (v1, operator, v2, options) {
        console.log(v1); //item - Here the value is coming as such and not the model value.
        console.log(v2);  // red
        console.log(operator); // ==
        console.log(options);
        switch (operator) {
        case '==':
            return (v1 == v2) ? options.fn(this) : options.inverse(this);
        case '===':
            return (v1 === v2) ? options.fn(this) : options.inverse(this);
        case '<':
            return (v1 < v2) ? options.fn(this) : options.inverse(this);
        case '<=':
            return (v1 <= v2) ? options.fn(this) : options.inverse(this);
        case '>':
            return (v1 > v2) ? options.fn(this) : options.inverse(this);
        case '>=':
            return (v1 >= v2) ? options.fn(this) : options.inverse(this);
        case '&&':
            return (v1 && v2) ? options.fn(this) : options.inverse(this);
        case '||':
            return (v1 || v2) ? options.fn(this) : options.inverse(this);
        default:
            return options.inverse(this);
        }
    });
    
    
    

    Here the value from the model is not passed to the custom helper.

    JSBin link –> http://emberjs.jsbin.com/mifoy/3/edit

    Thanks in advance jeevi

    Reply
    1. bendog

      Hi Jeevi,

      Thanks for your input on this (and the JSBin sample). It looks like “item” is passed as a string to the helper, instead of the variable value (cf. output of console.log(v1) ).

      Seems to be an ember problem. There’s a Stack overflow question that has a similar case scenario here http://stackoverflow.com/questions/13830290/how-do-i-pass-a-variable-to-a-handlebars-helper

      Reply
  22. Rajesh Sharma

    I also had problem of variables not being evaluated. This fixed the problem

    lvalue = Ember.Handlebars.get(this, lvalue) || lvalue;
    rvalue = Ember.Handlebars.get(this, rvalue) || rvalue;

    Reply
  23. Timothy Ruhle

    This is my final code that works for me and is invoked like this:

    
    {{compare a b}}
    {{compare a '<' b}}
    
    
    
    Ember.Handlebars.registerHelper('compare', function(lvalue, operator, rvalue, options) {
        var operators, result;
    
    if (arguments.length < 3) {
        throw new Error("Handlerbars Helper 'compare' needs 2 parameters");
    }
    
    if (options === undefined) {
        options = rvalue;
        rvalue = operator;
        operator = "===";
    }
    
    lvalue = Ember.Handlebars.get(this, lvalue, options) || lvalue;
    operator = Ember.Handlebars.get(this, operator, options) || operator;
    rvalue = Ember.Handlebars.get(this, rvalue, options) || rvalue;
    
    operators = {
        '==': function(l, r) {
            return l == r;
        },
        '===': function(l, r) {
            return l === r;
        },
        '!=': function(l, r) {
            return l != r;
        },
        '!==': function(l, r) {
            return l !== r;
        },
        '<': function(l, r) {
            return l < r;
        },
        '>': function(l, r) {
            return l > r;
        },
        '<=': function(l, r) {
            return l <= r;
        },
        '>=': function(l, r) {
            return l >= r;
        },
        'typeof': function(l, r) {
            return typeof l == r;
        }
    };
    
    if (!operators[operator]) {
        throw new Error("Handlerbars Helper 'compare' doesn't know the operator " + operator);
    }
    
    result = operators[operator](lvalue, rvalue);
    
    if (result) {
        return options.fn(this);
    } else {
        return options.inverse(this);
    }
    
    
    });

    Reply
    1. Manoj-GT

      Is this getting triggered every time when you the value of a or b getting changed?

      Reply
    2. Manoj-GT

      These are the two version of my helpers

      1

      Ember.Handlebars.helper(‘fullname’, function(lvalue, rvalue, options) { lvalue = Ember.Handlebars.get(this, lvalue) || lvalue; rvalue = Ember.Handlebars.get(this, rvalue) || rvalue; return lvalue + ‘ ‘ + rvalue; });

      2

      Ember.Handlebars.registerHelper(‘compare’, function(lvalue, rvalue, options) { lvalue = Ember.Handlebars.get(this, lvalue) || lvalue; rvalue = Ember.Handlebars.get(this, rvalue) || rvalue; if (arguments.length < 3) { throw new Error(“Handlerbars Helper ‘compare’ needs 2 parameters”); } operator = options.hash.operator || “==”;

      var operators = {
          '==':       function(l,r) { return l == r; },
          '===':      function(l,r) { return l === r; },
          '!=':       function(l,r) { return l != r; },
          '<':        function(l,r) { return l < r; },
          '>':        function(l,r) { return l > r; },
          '<=':       function(l,r) { return l <= r; },
          '>=':       function(l,r) { return l >= r; },
          'typeof':   function(l,r) { return typeof l == r; }
      }
      
      if (!operators[operator]) {
          throw new Error("Handlerbars Helper 'compare' doesn't know the operator "+operator);
      }
      
      var result = operators[operator](lvalue,rvalue);
      
      if( result ) {
          return options.fn(this);
      } else {
          return options.inverse(this);
      }
      

      });

      The #1 helper is an inline helper and #2 is a block helper.

      The issue I’m facing is, every time when the value of either lvalue or rvalue gets changed #1 (inline helper) is getting triggered but #2 (block helper) is not triggering. Kindly advice.

      Reply
  24. Sumit

    Hey, I am using express-handlebars and I am getting this strange error when I am trying to implement some helpers.

    It says, express handlebars has no method called ‘registerHelper’. Has anyone seen this kind of error before?

    Object # has no method 'registerHelper'

    My code is following

    
    var handlebars = require('express-handlebars');
    var app = express();
    var ehbs = handlebars.create({defaultLayout :'main'});
    
    app.engine('handlebars', ehbs.engine);
    app.set('view engine', 'handlebars');
    console.log(ehbs);
    ehbs.registerHelper('compare', function (lvalue, operator, rvalue, options) {
        var operators, result;
    
    if (arguments.length < 3) {
        throw new Error("Handlerbars Helper 'compare' needs 2 parameters");
    }
    
    if (options === undefined) {
        options = rvalue;
        rvalue = operator;
        operator = "===";
    }
    
    operators = {
        '==': function (l, r) { return l == r; },
        '===': function (l, r) { return l === r; },
        '!=': function (l, r) { return l != r; },
        '!==': function (l, r) { return l !== r; },
        '<': function (l, r) { return l < r; },
        '>': function (l, r) { return l > r; },
        '<=': function (l, r) { return l <= r; },
        '>=': function (l, r) { return l >= r; },
        'typeof': function (l, r) { return typeof l == r; }
    };
    
    if (!operators[operator]) {
        throw new Error("Handlerbars Helper 'compare' doesn't know the operator " + operator);
    }
    
    result = operators[operator](lvalue, rvalue);
    
    if (result) {
    return options.fn(this);
    
    
    } else {
        return options.inverse(this);
    }
    
    });
    
    Reply
    1. bendog

      Never used handlerbars express. Maybe ask on stack overflow.

      Reply
    2. rsilva

      I am also using express-handlebars and found the solution here: https://github.com/ericf/express-handlebars in case you’re still looking:

      var express = require(‘express’); var exphbs = require(‘express-handlebars’);

      var app = express();

      var hbs = exphbs.create({ // Specify helpers which are only registered on this instance. helpers: { foo: function () { return ‘FOO!’; }, bar: function () { return ‘BAR!’; } } });

      app.engine(‘handlebars’, hbs.engine); app.set(‘view engine’, ‘handlebars’);

      app.get(‘/’, function (req, res, next) { res.render(‘home’, { showTitle: true,

          // Override `foo` helper only for this rendering.
          helpers: {
              foo: function () { return 'foo.'; }
          }
      });
      

      });

      app.listen(3000);

      Reply
  25. Sumit

    hmm the operators arrive as their HTML entities in my helper function:

    “>”

    Reply
    1. Sumit

      like this:

      & g t ;

      Reply
    2. bendog

      Might need more info regarding your context

      Reply
  26. Aamir Afridi

    What if you want to pass as many params as you want so inside the helper you use arguments array. In this case how will you use options?

    Reply
    1. bendog

      Do you have a particular example in mind?

      Reply
  27. Rahul

    Thanks for the example.

    Reply
  28. Fabio Vedovelli

    Just thanks a lot!

    thia part here

    operator = options.hash.operator || “==”;

    is missing var statement.

    Other than that, works like a charm!

    Reply
    1. bendog

      Thank you, good point.

      I’ve updated the entry accordingly.

      Reply
  29. Angel

    very beautiful and helpful article :)

    Reply
  30. Piyush

    Really helpful appreciated!

    Reply
  31. Stefan

    I found the code very helpful when doing handlebars stuff.

    I searched, but could not find any statement about an applicable license under which you grant rights for the code. Without a license large organizations such as mine cannot use the code due to the legal uncertainty.

    Therefore I request that you either A) publicly assign one of the well-known Open Source licenses or B) agree (on Email) to license the code to UBS under such Open Source license.

    Assigning a license serves your interests as well because * more organizations will re-use your code (the reason why you published I assume) and * a lack of license also leaves you without protection against – others removing attribution of your code (falsely claiming the code is theirs) and – liability and damages claims due to malfunctions under unforeseen circumstances

    A permissive Open Source license template that covers the above aspects is the BSD 2-clause license template available at: http://opensource.org/licenses/BSD-2-Clause

    Please let me know whether you are willing to publicly assign a license, or license the code to UBS and under what license. Please do not hesitate to contact myself or the UBS Open Source Management department at SH-OSSMGT@ubs.com

    Thank you Stefan

    Reply
    1. bendog

      No worries. Licensed under MIT license (added footnote)

      Reply
      1. Stefan

        Dear Bendog, Thank you very much for your quick answer! Stefan

        Reply
  32. Adam

    Can’t manage to get this to work in the newer versions of Ember. Using registerHelper is not resolving the values of the bound variables, and using registerBoundHelper fails because it doesn’t support block helpers.

    Also the syntax {{#if (compare .. . ..)}} fails for the same reason. Any idea’s on how to fix this?

    Reply
  33. Adam

    Used these helpers instead: https://www.npmjs.com/package/ember-truth-helpers

    Worked out of the box

    Reply
    1. bendog

      Thanks for the link Adam.

      I haven’t used this in ember at all, but the link you sent looks like a great new alternative.

      Reply
  34. Larry

    Searched all over the internet for this. Thank you! Also love the color scheme and typography of your site.

    Reply
  35. Suhas Mohan Shitole

    How we can write below condition in mustache template. if(value <= 1)

    else{ }

    Thanks Suhas

    Reply
    1. bendog

      In mustache? You can’t.

      This Stackoverflow answer is a pretty good summary of it http://stackoverflow.com/a/8549006/192705

      Reply
  36. Suhas Mohan Shitole

    Thanks !

    Reply
  37. Damien McDonnell

    Mike Griffin’s method is perfect! Thanks for all your hard work.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *