1

I'm working on some CouchDB apps and it's been lots of fun. I'm also learning how to use Mustache.js for templating. My question is what is the best approach for templating when your data has many nested layers. Here's an example:

var jsondata = {
  post1: {
    title: "First blog post",
    author: "John",
    tags: ["awesome", "interesting", "philosophical"],
    comments: {
      julie: "I love it!",
      mark: "I hate it!"
    }
  },
  post2: {
    title: "Second blog post",
    author: "Jill",
    tags: ["extraordinary", "crazy", "nice"],
    comments: {
      julie: "I love it!",
      mark: "I hate it!"
  }
};

I realize it depends on the unique structure of the data, but is there a general approach that works well? Here are some I'm considering:

  • Extract nested data from the set, so that you have a collection of top level arrays, then use helper functions to compile those into a template.
  • Build the template to mirror the data, then use some crazy combination of $.each, templating and regular expressions to compile the template in one shot.
  • Break the compilation down into parts, and then pass through the template several times, until it's fully complete.

I'm pretty lost here, would love some help!

PS: I'm planning on separating blog posts, comments, and tags, into separate json docs, and then pulling them together with couchdb views and lists, so I'm still a bit uncertain on the resulting data structure.

Costa Michailidis
  • 7,691
  • 15
  • 72
  • 124

1 Answers1

1

First off all you can use what you have now with a slight modification (in order to render the comments you need to have a known key). If you can change the data you want to pass to the engine you could do something like this:

<script type="text/javascript">
    $(function () {
        var posts = {blogs:[
            {
                title:"First blog post",
                author:"John",
                tags:["awesome", "interesting", "philosophical"],
                comments:[
                    {name:"juli", comment:"I love it"},
                    {name:"foo", comment:"bar"}
                ]
            },
            {
                title:"Second blog post",
                author:"Jill",
                tags:["extraordinary", "crazy", "nice"],
                comments:[
                    {name:"juli", comment:"I love it"},
                    {name:"foo", comment:"bar"}
                ]
            }
        ]};
        var template = $("#template").html();
        var output = Mustache.render(template, posts);
        console.log(output);
    });
</script>
<script id="template" type="x-template">
    {{#blogs}}
    <div>{{title}}</div>
    <div>{{author}}</div>
    <ul>
       {{#tags}}
       <li>{{.}}</li>
       {{/tags}}
    </ul>
    <ul>
        {{#comments}}
        <li>{{name}}: {{comment}}</li>
        {{/comments}}
    </ul>
    {{/blogs}}
</script>

If you can't change the input, I suggest you go for Handlebars.js where you can write a helper function that extracts the key-val from the template data:

Have a look at this example by Michael Mior for details.

Working with many nested layers

When the data contains many nested layers, consider using partials to split the templates up. You could for example have one template for author one for tags and another for comments and nest them.

//Blog template
{{#blogs}}
  {{title}}
  ...
  //delegate rendering of tags to a partial template
  {{> tags}}
  {{> comments}}
{{/blogs}}

The Mustache doc contains more info on using partials.

Community
  • 1
  • 1
ebaxt
  • 8,287
  • 1
  • 34
  • 36
  • Very very helpful! The premise that the keys must be known is huge. I can use plain JavaScript to adjust my data so that the keys are known. You adjusted the data in only two places right? Blogs and Comments? Thanks!! – Costa Michailidis Mar 03 '12 at 23:27