railway

Sidebars and other dynamic content

In episode #100 of his screencasts, Ryan Bates shows - among other things - how dynamically fill elements of your layouts.

Imagine your layout contains a <div id=“sidebar”> where you want different sidebar content, depending on the page the user’s currently on. Ryan uses content_for(:side) which is definitely the way to go, but I think his approach isn’t as DRY as it could be.

Instead of using content_for(:side) in every template, I’d suggest extracting that bit in a helper method and put in in your ApplicationHelper module like that:

def sidebar(&block)
  content_for(:sidebar, &block)
end

After that, you can just call the newly created helper method in your views:

<% sidebar do %>
This goes in the sidebar!
<% end %>

This approach also gives you the opportunity to include some logic in the helper. Consider the possibility of showing an admin area as a part of the page if (and only if) the user has admin privileges. In one of my projects, I used something the following code:

def admin_area(section='', &block)
  if self.current_user.admin?
    concat(content_tag(:h2, "#{section.humanize} Admin", :class => "admin_options"), block.binding)
    concat(content_tag(:div, capture(&block), :class => "admin_options"), block.binding)
  end
end

In the views, it looks like this:

<% admin_area('forum') do %>
... display the admin area ...
<% end %>

This way, you keep logic out of the view so it stays nice and clean.