5

I am trying to put together a Rails app, with backbone.js and mustache templating. I am finding that the JSON required by backbone isn't compatible with the JSON required by Mustache. (I started out following this tutorial Cloudedit -a backbone.js tutorial by example, but I want to use Mustache where he is using JST.

For backbone we must set ActiveRecord::Base.include_root_in_json = false. For my model (person with firstname and surname) the data sent by rails from /people looks like this:

[{"firstname":"Jane","surname":"Jones"},{"firstname":"Janet","surname":"Jensen"}]

My mustache template looks like this:

<h3><a href='#new'>Create New</a></h3>
<h4>People</h4>
<ul>
{{#people}}
<li>{{firstname}} {{surname}}</li>
{{/people}}
</ul>

and from the mustache docs I expect that what it wants to see is

{"people":[{"firstname":"Jane","surname":"Jones"},{"firstname":"Janet","surname":"Jensen"}]}

Edited out me transforming the JS collection back to JSON and sending to Mustache. Don't need to do that. Mustache.js expects to see js objects, not strings of JSON.

By the time I get to Mustache.to_html I have a backbone collection of models. The models have the attributes firstname and surname. It looks like this in firebug:

collection
  +_byCid
  +_byId
   length 2
  - models  [object { attributes=(...), more...}, object {attributes=(...), more...}]
    - 0 object { attributes=(...), more...}
      ....... some more properties of the object
        + attributes object {firstname="Janet", surname="Jensen"}

There seem to be a couple of problems here. 1. There is no mention of the name of the collection (people). I can get around that in various ways I guess, at least by using {{#models}}..{{/models}} in the template.

  1. The attributes are buried deeper than Mustache.js looks. When it gets down to trying to find the 'firstname' tag in the object, it looks for object['firstname'] and doesn't find it, but object.attributes['firstname'] has the correct value.

It seems I'm all mixed up here....So what am I doing wrong? And how can I fix it?

Anita Graham
  • 456
  • 1
  • 5
  • 13
  • Can you provide the code used to initialize the template? – yves amsellem Jul 01 '11 at 09:47
  • Ah, and I guess you have [a possible answer there](http://stackoverflow.com/questions/6516297/can-mustache-iterate-a-top-level-array) – yves amsellem Jul 01 '11 at 09:49
  • 1
    Well, I went home and started afresh, rather than trying to experiment with an existing application. Found a minor problem, but in the end it came down to the same thing: Mustache is looking for data at object.firstname, but the data is in object.firstname.attributes. – Anita Graham Jul 02 '11 at 12:52
  • @yves - not sure what you mean by the code used to initialize the template? In my clean attempt to do this I have put the template directly into the variable passed to Mustache. Thus: tpl="

    ..."; out=Mustache.to_html(tpl,collection)

    – Anita Graham Jul 02 '11 at 12:53

2 Answers2

2

I now have a solution of a sort (thanks to this question).

jsonForTemplate = JSON.parse(JSON.stringify(this.people)); //this works for a single item
context['people']=jsonForTemplate;    //need to add this for a collection
out = Mustache.to_html(tpl,context);

but it feels as though this sort of jumping-through-hoops shouldn't be necessary. I will check to see if handlebars offers anything better.

Community
  • 1
  • 1
Anita Graham
  • 456
  • 1
  • 5
  • 13
  • This solved it for me also. Have you discovered a better way? Is mustache the wrong tool for use with backbone? – automagic Sep 09 '11 at 20:52
2

A simpler solution would be to use toJSON on the Collection as documented here - http://documentcloud.github.com/backbone/#Collection-toJSON

out = Mustache.to_html(tpl, collection.toJSON);
maxbeatty
  • 9,050
  • 3
  • 33
  • 36