How do I use nested iterators with Mustache.js or Handlebars.js?

Sorry I'm a little late in the game here. The accepted answer is great but I wanted to add an answer that I think is also useful, especially if you are iterating over simple row/column arrays.

When you're working with nested handlebar paths, you can use ../ to refer to the parent template context (see here for more information).

So for your example, you could do:

{{#each families}}
  {{#each members}}
    <p>{{../surname}}</p>
    <p>{{given}}</p>
  {{/each}}
{{/each}}

This was especially useful for me because I was making a grid and I wanted to give each square a class name corresponding to its row and column position. So if rows and columns, simply return arrays, I can do this:

<tbody>
  {{#each rows}}                                                           
    <tr>
      {{#each columns}}
        <td class="{{this}}{{../this}}"></td>
      {{/each}}
    </tr>
  {{/each}}
</tbody>

Update

This solution is for Handlebars. A comment below explains why it will not work in Mustache.


You can nest sections easily with lists of objects. Use a data structure where families is a list that has an object members that has a list of any objects (or even more lists)like:

{
  "families" : [
        {
          "surname": "Jones",
          "members": [
            {"given": "Jim"},
            {"given": "John"},
            {"given": "Jill"}
          ]
        },
        {
          "surname": "Smith",
          "members": [
            {"given": "Steve"},
            {"given": "Sally"}
          ]
        }
      ]
}

You would be able to populate a template like:

<ul>
    {{#families}}
    <li>{{surname}}
      <ul>
        {{#members}}
        <li>{{given}}</li>
        {{/members}}
      </ul>
    </li>
    {{/families}}
  </ul>

jsFiddle is currently down so here's the full working HTML with JS:

<!DOCTYPE html>
<head>

  <script src="http://cdnjs.cloudflare.com/ajax/libs/mustache.js/0.3.0/mustache.min.js"></script>
  <script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
  <script>
    $(function() {
      var tpl = $('#fam').html(),
        data = {
          "families" : [
            {
              "surname": "Jones",
              "members": [
                {"given": "Jim"},
                {"given": "John"},
                {"given": "Jill"}
              ]
            },
            {
              "surname": "Smith",
              "members": [
                {"given": "Steve"},
                {"given": "Sally"}
              ]
            }
          ]
        },
        html = Mustache.to_html(tpl, data);

        $("#main").append(html);

    });
  </script>

</head>

<div id="main"></div>

<script type="template/text" id="fam">
  <ul>
    {{#families}}
    <li>{{surname}}
      <ul>
        {{#members}}
        <li>{{given}}</li>
        {{/members}}
      </ul>
    </li>
    {{/families}}
  </ul>
</script>