Rails 3: yield/content_for with some default value?
Is there any way to detect if #content_for
was actually applied to a yield
scope in Rails?
A classic example being something like:
<title><%= yield :page_title %></title>
If a template doesn't set that with
<% content_for :page_title, "Something here" %>
Is there a way to have the layout put something else there instead?
I tried defining it with #content_for
in the layout itself, but this just causes the text to be doubled-up.开发者_运维技巧 I also tried:
<%= (yield :page_title) or default_page_title %>
Where #default_page_title
is a view helper.
This just left the block completely empty.
You can use content_for?
to check if there is content with a specific name:
<% if content_for?(:page_title) %>
<%= yield(:page_title) %>
<% else %>
<%= default_page_title %>
<% end %>
or
<%= content_for?(:page_title) ? yield(:page_title) : default_page_title %>
Then in your views you can specify the content like
<% content_for :page_title do %>
Awesome page
<% end %>
As of Rails 3, yield()
returns empty string if there was no content for the requested key, so you can do something like this:
<title><%= yield(:page_title).presence || 'Default Page Title' %></title>
In your application helper, if you define:
def page_title(title = nil)
title ? content_for(:page_title) { title } : content_for(:page_title).presence
end
Then you can do something like this:
<title><%= page_title or 'Default Page Title' %></title>
And in your views you can customize with:
<% page_title 'My Page Title' %>
Better answer for rails 3 here:
Yield and default case || do not output default case
<%= yield(:title).presence || 'My Default Title' %>
I have just released a new gem, dry_views, which provides enhanced content_for methods.
The benefit over the accepted answer is it allows you to remove all logic (if/else) from your views.
See the readme for extensive examples:
- no_content_for :key
- Use a dash (-) not equals (=)
- Will prevent a later content_for from rendering. This allows template overrides of layouts.
= content_for_with_default :key
- Use an equal (=) not a dash (-)
- You provide it with the default HAML via a block or a set of params that are the same as you would pass to a standard "render" call (i.e. :partial => 'foo', :locals => {:bar => 'bar'}).`
= content_for :key
- Use an equal (=) not a dash (-)
- You provide it with a block, i.e. {render :partial => 'foo'}, and it will override content_for_with_default. It has the same precedence as no_content_for, so whichever is rendered first wins, so if a layout has either no_content_for or content_for (with or without default) the template can now override it.
精彩评论