How do I accomplish an if/else in mustache.js?

June 2024 ยท 2 minute read

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?

5

5 Answers

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

7

This is something you solve in the "controller", which is the point of logicless templating.

// some function that retreived data through ajax function( view ){ if ( !view.avatar ) { // DEFAULTS can be a global settings object you define elsewhere // so that you don't have to maintain these values all over the place // in your code. view.avatar = DEFAULTS.AVATAR; } // do template stuff here } 

This is actually a LOT better then maintaining image url's or other media that might or might not change in your templates, but takes some getting used to. The point is to unlearn template tunnel vision, an avatar img url is bound to be used in other templates, are you going to maintain that url on X templates or a single DEFAULTS settings object? ;)

Another option is to do the following:

// augment view view.hasAvatar = !!view.avatar; view.noAvatar = !view.avatar; 

And in the template:

{{#hasAvatar}} SHOW AVATAR {{/hasAvatar}} {{#noAvatar}} SHOW DEFAULT {{/noAvatar}} 

But that's going against the whole meaning of logicless templating. If that's what you want to do, you want logical templating and you should not use Mustache, though do give it yourself a fair chance of learning this concept ;)

2

Your else statement should look like this (note the ^):

{{^avatar}} ... {{/avatar}} 

In mustache this is called 'Inverted sections'.

2

Note, you can use {{.}} to render the current context item.

{{#avatar}}{{.}}{{/avatar}} {{^avatar}}missing{{/avatar}} 
0

You can define a helper in the view. However, the conditional logic is somewhat limited. Moxy-Stencil (https://github.com/dcmox/moxyscript-stencil) seems to address this with "parameterized" helpers, eg:

{{isActive param}} 

and in the view:

view.isActive = function (path: string){ return path === this.path ? "class='active'" : '' } 

ncG1vNJzZmirpJawrLvVnqmfpJ%2Bse6S7zGiorp2jqbawutJobWlqZ2p%2FdnvHqK5mnJ9itm6twpympqicnsCpecCnZKKeXZq5tLGMoqVmpaWowaKvx55ko6s%3D