Modular Page Assembly in Rails

Downloads:
10 page pdf article only or article and sample code.

So, you've read “Agile Web Development with Rails”, and you've started to tinker with some pages on your own, but you just can't figure out how you're supposed to use that view file to create your 3 column layout?

So far I’ve found every tutorial on Rails talks about the default chain of controller to view to layout and stops. 3 files, done. Well, then what?

I felt your pain. So, I've prepared an article and sample code set (links up top) intended to pick up where AWDWR leaves off in explaining how to organize files for a modular page assemby approach with layouts and partials.If you’ve come from a template-driven web application framework, the way Rails builds pages can feel a bit backwards. For me, I was accustomed to the exact opposite of how Rails works. I'm used to the layout being the starting point, and its structure determining which view fragments the framework would include (based on dynamic file name conventions).

By the time I get to writing code for a site I have a pretty solid idea of how it will look, and how it needs to be structured. While AWDWR is a good intro, it left me feeling like I still had no idea how I was going to build typical modular web pages using layouts with reusable panels. Only after I figured this out was my brain going to feel free to work on the logical side of Rails.

So, I focused on solving that puzzle before I went much further. Out of that process, you get my first blog, and my first article about Rails. (I've written quite a bit about another language called Lasso).

I'll use your feedback to shape the article's updates. If you think I should address some particular idioms, let me know. My objective is to provide material that's more complete than the gloss-overs we usually get treated to in web articles.

Oct 22 Update: I have expanded the article to include the passing of data into the various display components. Indeed, solving this task to meet several goals required that I change how I was doing some things in the first version of the article.

Rails 2.0 changes some things like file extensions. The article isn't updated for these new details, but for the most part everything should still work for 2.0 code. I haven't made the jump myself. When I do, I'll update the article.

8 Comments so far

  1. Kenny Pate on November 1st, 2007

    Thanks very much for posting this. It’s very helpful.

  2. michal on November 15th, 2007

    brilliant article! I love (and really appreciate) that you focus on the approach and not on the technical stuff.

    i like that comment “.. and by the OOP police”

    btw: on page six you have a small typo:

    render(
    :partial => “newsHeadlines”,
    :locals => {
    :headlines = @topStories})

    should be

    render(
    :partial => “newsHeadlines”,
    :locals => {
    :headlines => @topStories})

    cheers michal

  3. Patrick on November 26th, 2007

    This is a great article. I had most of these methods in place but, had to go about figuring them out myself. I wish this article was around back then.

    I have one question though regarding your use of content_for.

    I have many view templates associated with actions in a single controller which all need to render the same content in my left and right columns with slight variation depending on the action. Isnt the fact that I have to put content_for :left and content_for :right a violation of DRY by repeating those code blocks every time. Even if I put both of those content_for blocks into a partial and call the partial from each of the view templates that still repeats code in each those templates.

    Some insight on this would be greatly appreciated.

  4. Greg Willits on November 27th, 2007

    @Patrick - Every design will have its own needs that will influence where you push the responsibility for declaring repetitive content. You’ll want to push it to where you have the least repetition without sacrificing any flexibility you need.

    However, at some point something has to declare on a “page by “page” basis what makes up that page. The task of declaring might feel redundant, but if its declaring something different every time, it’s really not. If the work involved 50 words of code and only 2 were were different every time, then yeah you might write yourself a method that does the 48 words of work, and takes two words as variables. Without an example, I can’t really say in your case which end of the scale you’re at.

    If you have panels with redundant content from action to action, then it may be a good candidate to make that content a partial that is included directly by the layout.

    If there’s data in those panels that are unique, you could use instance variables in the layout to pass them into the partials that get rendered as these panels.

    Is using instance vars OK? The view file and the layout are first-tier includes–that is, Rails itself dictates when they’re loaded and as far as I know there’s no prescribed way of creating local vars from the view for the layout, you just use instance vars like you would in the view.

    So, instead of content_for, you could use partials as you were thinking, but instead of doing that from the view, do it from the layout. That way it would apply to all actions using that layout.

    Remember, my article isn’t trying to prescribe “the” way, it’s just exploring different ways to do things. Mix, match, modify to get the right balance for your page and data design.

  5. WN on December 12th, 2007

    I tried to download your code to study it. But the link given http://www.railsdev.ws/articles/pageAssyForRails/
    pageAssyForRailsCode.zip
    to download from, does not exist.

    Great article, learned a lot. Thanks

  6. WN on December 12th, 2007

    I just found the download on this page, please ignore my previous post. Sorry my mistake.

  7. Greg Willits on December 12th, 2007

    @WN - where did you see that link? I’ll see if I can fix it. Thx.