305

It seems rather odd that I can't figure how to do this in mustache. Is it supported?

This is my sad attempt at trying:

    {{#author}}
      {{#avatar}}
        <img src="{{avatar}}"/>
      {{/avatar}}
      {{#!avatar}}
        <img src="/images/default_avatar.png" height="75" width="75" />
      {{/avatar}}
    {{/author}}

This obviously isn't right, but the documentation doesn't mention anything like this. The word "else" isn't even mentioned :(

Also, why is mustache designed this way? Is this sort of thing considered bad? Is it trying to force me to set the default value in the model itself? What about the cases where that isn't possible?

ViniciusPires
  • 983
  • 3
  • 12
  • 26
egervari
  • 22,372
  • 32
  • 121
  • 175
  • 1
    "why is mustache designed this way?" I'm not too sure, but I think the idea is that a templating language should be just that: a language for writing templates, i.e. things that look like the output they produce, just with holes where the variable bits go. Putting logic in the template language makes the templates more complicated, and when you've already got a programming language to handle the logic bits, why bother? – Paul D. Waite Sep 06 '13 at 11:05
  • 6
    @PaulD.Waite "Logic-less" really means "non-arbitrary code," I think. It's just as bad to put true view logic in code as it is to put non-view logic in a template. Mustache tries to provide a bare minimum logic to accomplish that. – jpmc26 Aug 21 '14 at 16:57
  • 2
    Or use [handlebars](http://handlebarsjs.com/builtin_helpers.html) instead of mustache. Being able to write, e.g. `{{#each items}}{{#unless @first}}Output comma before 2nd, 3rd, 4th...{{/unless}}{{/each}}` is more readable, much cleaner, and is still presentation. "Logic-less" is a guideline, it doesn't have to be a straitjacket. – skierpage Jul 28 '15 at 05:08
  • Maybe it's not a versatile-enough templating engine when an OP says "this is my sad attempt [...] this obviously isn't right" ...and then the accepted answer is a copy-paste of that code :). No judgment on OP or answer; just on `mustache` – dwanderson Sep 21 '17 at 17:31
  • if you're on PHP, try `sm-mustache`, i've implemented `|` else block to cut those extra declarations.. – Michael Quad Jul 05 '21 at 02:02

5 Answers5

579

This is how you do if/else in Mustache (perfectly supported):

{{#repo}}
  <b>{{name}}</b>
{{/repo}}
{{^repo}}
  No repos :(
{{/repo}}

Or in your case:

{{#author}}
  {{#avatar}}
    <img src="{{avatar}}"/>
  {{/avatar}}
  {{^avatar}}
    <img src="/images/default_avatar.png" height="75" width="75" />
  {{/avatar}}
{{/author}}

Look for inverted sections in the docs: https://github.com/janl/mustache.js#inverted-sections

Community
  • 1
  • 1
Eneko Alonso
  • 18,884
  • 9
  • 62
  • 84
  • 132
    The mustache docs are hilarious. "We call it "logic-less" because there are no if statements, else clauses, or for loops." Yeeeeaaaaaa.... – boxed Nov 10 '15 at 13:25
  • 8
    @boxed, technically you're right, the inverted section is a logical statement, as it checks the tag value. But, I think the nuance here is that both statements have to be explicitly evaluated, rather than a single if/else. Basically, mustache forces the structure `if (condition){ //do something}` followed by a `if (!condition){//do something else}`. Also, the amount of logic that one can perform in logic extremely reduced compared to a logic-based language. Existence or non-existence are the only checks, i.e. you can't check if the value of a tag equals 5 and then fall into that tag's code. – MandM Nov 13 '15 at 19:21
  • 29
    @MandM yea... so it has logic but it just can't do anything useful :P – boxed Jan 05 '16 at 12:30
  • 1
    It just keeps you way from messing with if else logic . Having a lot of nested if/else inside another if/else is a sign of misdesign – Tebe Dec 13 '17 at 12:41
  • @boxed you can do for loop with moustache.js (at least ngFor-ish loop) – aloisdg Jun 22 '18 at 08:26
  • basically I need something like this
  • – zEn feeLo Nov 30 '18 at 21:18
  • Mustache is logic-less because indeed it forces you to put business logic outside of the view, which is a good thing. If you are wondering how to do an if/else in a view you're most likely doing it wrong, and should move that logic to the controller. Refactoring in that way keeps the views much cleaner and simpler. – laurent Dec 13 '20 at 12:49