Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Backbone.Marionette.ItemView with Mustache

The following code works fine using Backbone.Marionette.ItemView but not Mustache.

Backbone.Marionette.ItemView - no Mustache

I would like to use the same code but loading the template varaible using Mustache.

Here is my code:

Backbone.Marionette.ItemView - with Mustache

Any idea why my code does not work and why?

Thanks

like image 275
Lorraine Bernard Avatar asked Jun 18 '12 13:06

Lorraine Bernard


2 Answers

I'd like to update the answer here a bit as I was just struggling with this, and I was using this answer as a reference.

Here are my findings:

The answer here is a bit out of date with the current version of Mustache (which is understandable as it's pretty old)

  • Mustache.to_html is now deprecated, but still exists as a simple wrapper around Mustache.render for backwards compat. Check out this link.

Additionally, I found overriding Marionette.Renderer.render, as in the accepted answer above, completely bypasses the Marionette.TemplateCache layer which may not be the desired behavior.

Here's the source for the Marionette.Renderer.render method:

render: function(template, data){

  if (!template) {
    var error = new Error("Cannot render the template since it's false, null or undefined.");
    error.name = "TemplateNotFoundError";
    throw error;
  }

  var templateFunc;
  if (typeof template === "function"){
    templateFunc = template;
  } else {
    templateFunc = Marionette.TemplateCache.get(template);
  }

  return templateFunc(data);
}

Source

As you can see it accesses the Marionette.TemplateCache.get method and the above answer does nothing to maintain that functionality.

Now to get to my solve (note: the above answer is not wrong necessarily; this is just my approach to maintain the Marionette.TemplateCache layer):

As the comments suggest above, override compileTemplate instead:

Marionette.TemplateCache.prototype.compileTemplate = function(rawTemplate) {

    // Mustache.parse will not return anything useful (returns an array)
    // The render function from Marionette.Renderer.render expects a function
    // so instead pass a partial of Mustache.render 
    // with rawTemplate as the initial parameter.

    // Additionally Mustache.compile no longer exists so we must use parse.
    Mustache.parse(rawTemplate);
    return _.partial(Mustache.render, rawTemplate);
};

Here's a working JSFiddle as proof.

In the fiddle, I've also overridden Marionette.TemplateCache.loadTemplate to demonstrate that it's only called once. The body of the function only adds some debug output and then re-implements most of the original functionality (minus error handling).

like image 148
Aubricus Avatar answered Jan 04 '23 09:01

Aubricus


Marionette assumes the use of UnderscoreJS templates by default. Simply replacing the template configuration for a view isn't enough. You also need to replace how the rendering process works.

In your simple example, you only need to override the Marionette.Renderer.render function to call Mustache, and then set the template of your views to the string template that you want:


Backbone.Marionette.Renderer.render = function(template, data){
  return Mustache.to_html(template, data);
}

var rowTemplate = '{{ username }}{{ fullname }}';

// A Grid Row
var GridRow = Backbone.Marionette.ItemView.extend({
    template: rowTemplate,
    tagName: "tr"
});

Note that your JSFiddle still won't work even when you put this code in place, because the GridView is still using a jQuery selector/string as the template attribute. You'll need to replace this with the same type of template function to return mustache.

http://jsfiddle.net/derickbailey/d7qDz/

like image 41
Derick Bailey Avatar answered Jan 04 '23 10:01

Derick Bailey