Content_for, yield and making sure something gets displayed

1 September 2007

You may have heard of a very nice Rails technique that used content_for and yield to stuff custom blocks of content into a layout. For example, in a view you could add a block like this:

<% content_for :sidebar do %>
  This goes into the sidebar when viewing this action!
<% end %>
It doesn’t matter where you put it in the view, because, as you may notice, the content within the content_for block is not shown in the view. The layout can pull the content for :sidebar and show it in a custom place, mostly the sidebar:
<%= yield :sidebar %>
Nice, you now don’t have to hard-code the sidebar (and it’s layout elements) in your views everytime. You can even move the sidebar to another place, without breaking any of your views. How great is that?

What does break your views, however, is not assigning anything to :sidebar. If you don’t assign anything to the :sidebar, nothing will be shown, which might break your layout. (Empty div’s tend to do that.)

So, how can you solve this? Quite easily, actually. What you want, probably, is display a default sidebar when no custom sidebar has been assigned. you can do this with the following line of über sexy Ruby code:

<%= (sidebar = yield :sidebar) ? sidebar : render(:partial => ‘shared/sidebar’) %>
First, you grab the :sidebar content and stuff it into a variable named, you guessed it, ‘sidebar’. If this sidebar containts anything, show it. If it doesn’t, you render a partial in the app/views/shared directory named _sidebar.rhtml.

Well, there you are. Go enjoy yourself now.