7

I'm migrating a Website from Rails 2 (latest) to Rails 3 (beta2).
Testing with Ruby 1.9.1p378 and Ruby 1.9.2dev (2010-04-05 trunk 27225)

Stuck in a situation, i don't know which part will work well. Suspect yield is the problem, but don't know exactly.

In my Layout Files I use the following technique quite often:

app/views/layouts/application.html.erb:

<%= yield(:sidebar) || render('shared/sidebar') %>

For Example the partial look like:

app/views/shared/_sidebar.html.erb:

<p>Default sidebar Content. Bla Bla</p>

Now it is time for the key part!
In any view, I want to create a content_for block (optional). This can contain a pice of HTML etc. example below. If this block is set, the pice HTML inside should render in application.html.erb.
If not, Rails should render the Partial at shared/_sidebar.html.erb on the right hand side.

app/views/books/index.html.erb:

<% content_for :sidebar do %>
    <strong>You have to read REWORK, a book from 37signals!</strong>
<% end %>

So you've got the idea. Hopefully. This technique worked well in any Rails 2.x Application.
Now, in Rails 3 (beta2) only the yield Part is working.

|| render('shared/sidebar')

The or side will not process by rails or maybe ruby.

Thanks for input and time!

Jon Seigel
  • 12,251
  • 8
  • 58
  • 92
rzar
  • 1,236
  • 1
  • 13
  • 9

4 Answers4

7

Ryan Bates from railscasts.com shows in Episode #227 - Upgrading to Rails 3 Part 3 a solution with content_for?() (video playback at 2:45 Min)

I think, that's the way we should use it:

content_for?(:sidebar) ? yield(:sidebar) : render("shared/sidebar")
rzar
  • 1,236
  • 1
  • 13
  • 9
3

Thanks Mike Dotterer. I took your idea and modified it a bit.

yield(:sidebar).presence || render("shared/sidebar")

object.presence is equivalent to object.present? ? object : nil

provide vs content_for

Jason Deppen
  • 171
  • 3
3

I tested this out and it looks like Rails 3 is returning empty string instead of nil. So, unless they change this before the final release you will have to modify your code to see if the value is blank instead of just nil.

(sidebar = yield(:sidebar)).present? ? sidebar : render("shared/sidebar")
Mike Dotterer
  • 1,198
  • 1
  • 11
  • 19
3

I usually set my site title with:

<title><%= ['My Site', yield(:title)].compact.join(' - ') %></title>

Due to this change, it would be ugly to add some conditions, so I created a helper like this:

module ApplicationHelper
    def nil_empty(str)
        str.blank? ? nil : str
    end
end

Then I can do something like:

<title><%= ['My Site', nil_empty(yield :title)].compact.join(' - ') %></title>

It's still ugly, but a little bit less :)

WEFX
  • 8,298
  • 8
  • 66
  • 102
Pixoo
  • 31
  • 2