backbone.jsejsjst

how to use includes/partials in Rails 3 Backbone ejs.jst files


I'm using the backbone-on-rails gem with javascript (as opposed to coffeescript) to render views for a model. Everything works fine, but my view code is kind of long so I'd like to refactor things out to use includes/partials.

Heres' my code:

in my views/model_show.js file

AppName.Views.ModelNameShow = Backbone.View.extend({

  template: JST['main'],

  initialize: function() {
    this.render();
  },

  render: function() {
    this.model.fetch({async:false});
    $(this.el).html(this.template({ model: this.model }))
    $('#main_content').html(this.el);
  }

});

in my templates file I'd like to so something like this in templates/main.jst.ejs

<% if(this.model) { %>
    <h2> model found</h2> 
    <%- include top_section %>
    <%- include middle_section %>
    <%- include bottom_section %>
<% } else { %> 
    <h3>Claim not found <a href='#'>Back</a></h3> 
<% } %>

where top_section would be a file under templates (like templates/top_section.jst.ejs)

Problem is I keep getting the following errors (firebug output).

SyntaxError: missing ) in parenthetical [Break On This Error]

...2> model found \n\t',(''+ include top_section ).replace(/&/g, '&').replace(/

which causes this error because the template isn't rendered

TypeError: this.template is not a function
[Break On This Error]   

$(this.el).html(this.template({ model: this.model }))

I should mention that I've tried a few different syntaxes like the ones below, but those just throw different errors.

<%= include top_section %>
<%- include(top_section) %>

Thanks in advance


Solution

  • As a stop-gap for now I just created a hash of templates and enumerate over them in the render. Not ideal, but works for now. Here's what the code looks like now.

    views/model_show.js file

    AppName.Views.ModelNameShow = Backbone.View.extend({
    
      templates: {
        top_section: JST['top_section'],
        middle_section: JST['middle_section'],
        bottom_section: JST['bottom_section']
      },
    
      initialize: function() {
        this.render();
      },
    
      render: function() {
        this.model.fetch({async:false});
        var zuper = this;
        $.each(this.templates, function(key, value) {
          //iterate over each template and set the html for the div with id=key with template
          //For example $('#top_section).html(JST template for top_section)
          $('#' + key).html(zuper.templates[key]({ model: zuper.model }))
        })
      }
    
    });
    

    template file looks like this now.

    <% if(this.model) { %>
        <h2> model found</h2> 
        <div id="top_section"/>
        <div id="middle_section"/>
        <div id="include bottom_section"/>
    <% } else { %> 
        <h3>Model not found <a href='#'>Back</a></h3> 
    <% } %>
    

    As I said -- not ideal, but a functional workaround for now.