Search code examples
templatesmustacheoverriding

Mustache section values are overridden


How to get this output:

<h1>Colors</h1>
<li><strong>red</strong></li>
<li><a href="#Green">green</a></li>
<li><a href="#Blue">blue</a></li>

From this template:

<h1>{{header}}</h1>
{{#bug}}
{{/bug}}

{{#items}}
  {{#first}}
    <li><strong>{{name}}</strong></li>
  {{/first}}
  {{#link}}
    <li><a href="{{url}}">{{name}}</a></li>
  {{/link}}
{{/items}}

{{#empty}}
  <p>The list is empty.</p>
{{/empty}}

This data:

{
  "header": "Colors",
  "first": true,
  "items": [
      {"name": "red", "first": true, "url": "#Red"},
      {"name": "green", "link": true, "url": "#Green"},
      {"name": "blue", "link": true, "url": "#Blue"}
  ],
  "empty": false
}

So that the first field is not overridden.

Currently I get this output:

<h1>Colors</h1>
<li><strong>red</strong></li>
<li><strong>green</strong></li>
<li><a href="#Green">green</a></li>
<li><strong>blue</strong></li>
<li><a href="#Blue">blue</a></li>

I'm testing here.


Solution

  • The first key is defined at two levels: at the item level, and at the root level.

    When it is not defined at the item level, the Mustache engines digs in, and uses the one defined at the root level. This is called the Mustache context stack, and you have just learnt it the hard way.

    Now the answer is simple, insn't it? In order to prevent the Mustache engine to dig in the context stack and look for first at the root level, make sure first is defined at the item level, for all items. Set it to false for all items but the first.