开发者

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.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜