Dirty Views? Clean them up!

Posted on March 27, 2007

I feel the area where I need to improve most is in cleaning up my views. I feel like I’ve done a good job cleaning up my controllers and models, thanks to posts like Skinny Controller, Fat Model.

I have known about the content_for in rails views. Which basically allows you to have a layout like so:

<html>
    <head>
    </head>

    <body>
        <div id="wrapper">
            <div id="header">
                <% yield :header %>
            </div>

            <div id="content">
                <%= yield %>
            </div>

            <div id="sidebar">
                <% yield :sidebar %>
            </div>

            <div id="footer">
                <% yield :footer %>
            </div>
        </div>
    </body>
</html>

And in your view the following:


  <% content_for :header do %>
       This would appear for the yield :header call
  <% end %>

  <% content_for :sidebar do %>
      This is the sidebar content
   <% end %>

  <% content_for :footer do %>
     This is the footer content
  <% end %>

   <%# the rest would just be the content for the plain yield call %>
    This is would be my main content

This is nice, but I wanted to find a way to supply default content and this is what I came up with.

  def yield_with_default(yield_on, content=nil, &block)
    yield_content = eval "@content_for_#{yield_on} || ''" 
    if block_given?(&block)
      concat(yield_content.empty? ? capture(&block) : yield_content, block.binding)
    else
      Binding.of_caller do |binding|
        concat(yield_content.empty? ? content : yield_content, binding)
      end
    end
  end

I placed this in my application_helper.rb file. And now I can add something like this to my view.


    # with a block
    <% yield_with_default :header do %>
        This is my DEFAULT header content
    <% end %>

   # without a block
   <% yield_with_default :header, "This would be my default content" %>

This feels pretty clean to me. But if anybody has any other suggestions I would love to hear them.

I am also looking for more information on best practices with views in Rails. There doesn’t seem to be much information on the subject.

UPDATED: 04/01/2007 – forgot the do in the content_for statements