DRY(er) Rails view templates
Something I keep coming across when working with Ruby on Rails view templates, is wrapping blocks of content in common DIV tags with certain properties, so I can easily style the application with CSS.
For example, a page can have multiple content boxes, and possibly a sidebar with a number of info boxes. What I used to do, was something like this:
<div id="sidebar">
<div class="infobox">
Here is some help
</div>
</div>
<div class="content_box">
<%= render :partial => "table", :locals => {:people => @people} %>
</div>
Instead, by looking at the implementaton of the content_tag_for ActionView helper, I was able to find a way to do this:
<% sidebar do %>
<% infobox do %>
Here is some help
<% end %>
<% end %>
<% content_box do %>
<%= render :partial => "table", :locals => {:people => @people} %>
<% end %>
The "raw DIV tag approach" works, but there is a lot of repeated text strings (the ids and classes of the DIV tags), and if I some day want to add another stylesheet class to the content boxes, or maybe rename the content_box class to something else, I have to go though all of my view templates.
The second was made possible by adding methods similar to the following to my application_helper.rb:
def content_box(&block)
concat content_tag(:div, capture(&block), :class => "content_box"), block.binding
end
What is does is essentially capturing the html output within the block given, and wrapping it in a DIV tag with the given parameters. That way, the ids and classes I want to use are defined in one place, and easily changed. I can even decide to wrap the contents of the content box in a different tag, such as a SPAN, if I want to at some point.
To me this approach is DRY(er), and looks more like the rails form helpers (which I think is a plus). I don't know, however, if there are any performance-disadvantages to using this approach. Do you?
Continue Reading…Posted by Erik L. Underbjerg on Oct 03, 2008
