Martin Dimitrov
Martin Dimitrov

Reputation: 4956

Presentation logic inside mustache.js template engine

What is the simplest way to achieve the following presentation with client-side mustache.js template engine?

var view = {
  search_term: 'something',
  number_of_hits: 3,
  hits: [...]
};

If number_of_hits == 0 then print on screen: "No results found"

If number_of_hits == 1 then print on screen: "One result found"

If number_of_hits > 1 then print on screen: "N results found"

Knowing that mustache is logic-less template engine, is it at all possible to do it with the existing mustache tags or I will have to change the JSON respond?

Upvotes: 1

Views: 410

Answers (1)

jevakallio
jevakallio

Reputation: 35890

With Mustache it's possible to differentiate between the value 0 and non-0 values using the {{#section}} and {{^inverted}} tags:

<!-- If number_of_hits is not 0, show hits -->
{{#number_of_hits}}
 {{number_of_hits}} hits
{{/number_of_hits}}

<!-- If number of hits is 0 (or any other falsy value) -->
{{^number_of_hits}}
  No hits
{{/number_of_hits}}

As far as I know, Mustache cannot detect the difference between 1 and 2, for instance. For that you'll have to modify the viewobject you pass into the template. Possibly something like:

var hits = 3;
var view = {
  search_term: 'something',
  number_of_hits: hits,
  hitkind: { 
    none: hits === 0,
    one:  hits === 1,
    many: hits > 1
  }
};

And in the template

{{#hitkind.none}} No hits {{/hitkind.none}}
{{#hitkind.one }} One hit {{/hitkind.one}}
{{#hitkind.many}} {{number_of_hits}} hits {{/hitkind.many}}

Alternatively you could consider changing your templating engine to Handlebars.js. Handlebars is a superset of Mustache, which means that all your Mustache templates will work with it. Handlebars templates are logicless just like Mustache's, so it doesn't enable you to write the logic directly to the template. Instead it provides a concept of Helpers, or functions callable from your templates.

With Handlebars you can define a helper, like:

Handlebars.registerHelper('hitCount', function(count) {
  if(count === 0) return "No hits";
  if(count === 1) return "One hit";
  return count + " hits".
});

And call it from a template:

{{hitCount number_of_hits}}

Upvotes: 1

Related Questions