2010-03-08 08:46:57 -05:00
|
|
|
module ActionView
|
2010-06-16 14:27:50 -04:00
|
|
|
# = Action View Layouts
|
2010-03-08 08:46:57 -05:00
|
|
|
module Layouts
|
2010-04-05 05:16:24 -04:00
|
|
|
# Returns the contents that are yielded to a layout, given a name or a block.
|
2010-03-08 08:46:57 -05:00
|
|
|
#
|
2010-04-05 05:16:24 -04:00
|
|
|
# You can think of a layout as a method that is called with a block. If the user calls
|
|
|
|
# <tt>yield :some_name</tt>, the block, by default, returns <tt>content_for(:some_name)</tt>.
|
|
|
|
# If the user calls simply +yield+, the default block returns <tt>content_for(:layout)</tt>.
|
2010-03-08 08:46:57 -05:00
|
|
|
#
|
2010-04-05 05:16:24 -04:00
|
|
|
# The user can override this default by passing a block to the layout:
|
2010-03-08 08:46:57 -05:00
|
|
|
#
|
|
|
|
# # The template
|
2010-04-05 05:16:24 -04:00
|
|
|
# <%= render :layout => "my_layout" do %>
|
|
|
|
# Content
|
|
|
|
# <% end %>
|
2010-03-08 08:46:57 -05:00
|
|
|
#
|
|
|
|
# # The layout
|
2010-04-05 05:16:24 -04:00
|
|
|
# <html>
|
|
|
|
# <%= yield %>
|
|
|
|
# </html>
|
2010-03-08 08:46:57 -05:00
|
|
|
#
|
2010-04-05 05:16:24 -04:00
|
|
|
# In this case, instead of the default block, which would return <tt>content_for(:layout)</tt>,
|
|
|
|
# this method returns the block that was passed in to <tt>render :layout</tt>, and the response
|
|
|
|
# would be
|
2010-03-08 08:46:57 -05:00
|
|
|
#
|
2010-04-05 05:16:24 -04:00
|
|
|
# <html>
|
|
|
|
# Content
|
|
|
|
# </html>
|
2010-03-08 08:46:57 -05:00
|
|
|
#
|
2010-04-05 05:16:24 -04:00
|
|
|
# Finally, the block can take block arguments, which can be passed in by +yield+:
|
2010-03-08 08:46:57 -05:00
|
|
|
#
|
|
|
|
# # The template
|
2010-04-05 05:16:24 -04:00
|
|
|
# <%= render :layout => "my_layout" do |customer| %>
|
|
|
|
# Hello <%= customer.name %>
|
|
|
|
# <% end %>
|
2010-03-08 08:46:57 -05:00
|
|
|
#
|
|
|
|
# # The layout
|
2010-04-05 05:16:24 -04:00
|
|
|
# <html>
|
|
|
|
# <%= yield Struct.new(:name).new("David") %>
|
|
|
|
# </html>
|
2010-03-08 08:46:57 -05:00
|
|
|
#
|
|
|
|
# In this case, the layout would receive the block passed into <tt>render :layout</tt>,
|
2010-04-05 05:16:24 -04:00
|
|
|
# and the struct specified would be passed into the block as an argument. The result
|
|
|
|
# would be
|
|
|
|
#
|
|
|
|
# <html>
|
|
|
|
# Hello David
|
|
|
|
# </html>
|
|
|
|
#
|
2010-03-08 08:46:57 -05:00
|
|
|
def _layout_for(name = nil, &block) #:nodoc:
|
|
|
|
if !block || name
|
2010-04-09 12:14:02 -04:00
|
|
|
@_content_for[name || :layout].html_safe
|
2010-03-08 08:46:57 -05:00
|
|
|
else
|
|
|
|
capture(&block)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# This is the method which actually finds the layout using details in the lookup
|
2010-06-11 06:15:34 -04:00
|
|
|
# context object. If no layout is found, it checks if at least a layout with
|
2010-03-08 08:46:57 -05:00
|
|
|
# the given name exists across all details before raising the error.
|
2010-03-16 18:35:45 -04:00
|
|
|
def find_layout(layout)
|
2010-03-08 08:46:57 -05:00
|
|
|
begin
|
2010-06-07 04:13:41 -04:00
|
|
|
with_layout_format do
|
|
|
|
layout =~ /^\// ?
|
|
|
|
with_fallbacks { find_template(layout) } : find_template(layout)
|
2010-03-16 18:35:45 -04:00
|
|
|
end
|
2010-03-08 08:46:57 -05:00
|
|
|
rescue ActionView::MissingTemplate => e
|
|
|
|
update_details(:formats => nil) do
|
2010-03-12 08:25:10 -05:00
|
|
|
raise unless template_exists?(layout)
|
2010-03-08 08:46:57 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# Contains the logic that actually renders the layout.
|
|
|
|
def _render_layout(layout, locals, &block) #:nodoc:
|
|
|
|
layout.render(self, locals){ |*name| _layout_for(*name, &block) }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|