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!
During a method invocation The yield keyword in corporation with a block allows to pass a set of additional instructions. When yield is called in side a method then method requires a block with in it. A block is simply a chunk of code, and yield allows us to inject that code at some place into a method.
yield is a keyword in Ruby which allow the developer to pass some argument to block from the yield, the number of the argument passed to the block has no limitations, the main advantage of using yield in Ruby, if we face any situation we wanted to our method perform different functions according to calling block, which ...
Without any arguments, yield will render the template of the current controller/action. So if you're on the cars/show page, it will render views/cars/show. html. erb . When you pass yield an argument, it lets you define content in your templates that you want to be rendered outside of that template.
yield tells ruby to call the block passed to the method, giving it its argument. yield will produce an error if the method wasn't called with a block where as return statement don't produces error.
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")
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")
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 :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With