0

Currently transitioning a Rails 3.2+ app over to using Backbone.js to manage its front-end. Pre-transition, the app has several layout partials rendered within application.html.erb. To visualize, think grooveshark - with its left column and footer, where all navigation happens in a central content area. Point being, the content in the left/right columns, footer and header is not static.

Here's what I was thinking an application.jst.eco could look like. Where each commented line is a place another template could be rendered.

<!-- layouts/header -->

<div class="row-fluid">
  <div id="left-column" class="span3">
    <!-- layouts/left_column -->
  </div>

  <div class="span6">
    <section id="content">
      <header>
        <!-- notices -->
      </header>
      <!-- main content -->
    </section>
  </div>

  <div id="right-column"class="span3">
    <!-- layouts/right_column -->
  </div>
</div>

<!-- layouts/footer -->

How should I go about organizing templates in Backbone to replicate my application.html.erb structure? Am I even thinking in the right direction with this?

Further, I'm confused about the entry point of the Backbone application. Since I'll still be making a <%= yield %> call in application.html.erb, and pre-loading home page data through an erb view, how would this all come together if the greater layout is defined in Backbone templates?

anxiety
  • 1,689
  • 16
  • 25

1 Answers1

1

There are a variety of ways to do this, but just as an example here's how I do it.

First, you don't actually have to use your rails partials at all, unless support for non-javascript enabled browsers is a concern. The typical flow for a backbone.js app is:

  1. Server renders basic layout including <head>, <body> etc. but with placeholders for actual content. So for example, in my app I have placeholders for the navbar and one for the main content.
  2. Your main app class (usually App) in your backbone application creates a router, and either from the router's initialize method or from the route handler for whatever page you're on, you create and render views into your placeholders on the page. In my case since the navbar is never swapped out, I render that in the router's initialize method and then I render the actual page in the route handler. (Read this post for some important tips on how to actually render views on the page.)
  3. If you want to have composite views (say for example a list of items, where each item has its own view), then you'll be rendering those views in the parent and attaching them to the parent's element (not directly to the document). This keeps elements of your page separate which is important.
  4. Backbone is started (via Backbone.history.start) and from there on, backbone takes over.

In your case, you'll probably want to create views for each of your left/right columns and for your main content and header (notices), in the case of the latter two (header and main content) perhaps as a composite view.

Hope that helps, can provide more detail, just ask specific questions. p.s. I use backbone-support for rendering composite views to make sure that they are properly removed and unbound from the DOM when swapped, to avoid memory leaks, etc.

Chris Salzberg
  • 27,099
  • 4
  • 75
  • 82
  • Haha nah, it's a legit single-page app. Wasn't planning on using rails partials, seems like a step backwards if you're aiming not to render any more server-side templates than you absolutely have to. Sounds like a good direction though, thanks. And thanks for linking that gem, was already planning how to do that manually - relief. – anxiety Aug 26 '12 at 10:33
  • Yeah if you're using pushState then I actually think it's not a bad idea to render server-side views for any pages you actually route to (which can be just a subset of all views), to support non-js requests. I do it for GET requests only. I wrote about the issue in an answer to another question: http://stackoverflow.com/questions/11918586/rails-and-backbone-working-together/11922573#11922573 – Chris Salzberg Aug 26 '12 at 11:14