问题
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!
回答1:
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")
回答2:
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")
回答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 :)
回答4:
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
来源:https://stackoverflow.com/questions/2611278/rails-3-yield-return-or-callback-wont-call-in-view-yieldsidebar-ren