From b4a91db441fa9583df24fb8d3cf0d6906e8359db Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Wed, 17 Jun 2009 18:55:10 -0700 Subject: Extract the layout proc into a method, and write documentation explaining what the proc does in various cases. --- .../lib/action_view/helpers/capture_helper.rb | 4 -- actionpack/lib/action_view/render/rendering.rb | 43 +++++++++++++++++++--- 2 files changed, 38 insertions(+), 9 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb index 1c29eb3b81..a8b5a9dbb9 100644 --- a/actionpack/lib/action_view/helpers/capture_helper.rb +++ b/actionpack/lib/action_view/helpers/capture_helper.rb @@ -111,10 +111,6 @@ module ActionView # # WARNING: content_for is ignored in caches. So you shouldn't use it # for elements that will be fragment cached. - # - # The deprecated way of accessing a content_for block is to use an instance variable - # named @content_for_#{name_of_the_content_block}. The preferred usage is now - # <%= yield :footer %>. def content_for(name, content = nil, &block) content = capture(&block) if block_given? return @_content_for[name] << content if content diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb index a720012d1c..588a64a652 100644 --- a/actionpack/lib/action_view/render/rendering.rb +++ b/actionpack/lib/action_view/render/rendering.rb @@ -60,16 +60,49 @@ module ActionView end end + # You can think of a layout as a method that is called with a block. This method + # returns the block that the layout is called with. If the user calls yield :some_name, + # the block, by default, returns content_for(:some_name). If the user calls yield, + # the default block returns content_for(:layout). + # + # The user can override this default by passing a block to the layout. + # + # ==== Example + # + # # The template + # <% render :layout => "my_layout" do %>Content<% end %> + # + # # The layout + # <% yield %> + # + # In this case, instead of the default block, which would return content_for(:layout), + # this method returns the block that was passed in to render layout, and the response + # would be Content. + # + # Finally, the block can take block arguments, which can be passed in by yield. + # + # ==== Example + # + # # The template + # <% render :layout => "my_layout" do |name| %>Hello <%= customer.name %><% end %> + # + # # The layout + # <% yield Struct.new(:name).new("David") %> + # + # In this case, the layout would receive the block passed into render :layout, + # and the Struct specified in the layout would be passed into the block. The result + # would be Hello David. + def layout_proc(name) + @_default_layout ||= proc { |*names| @_content_for[names.first || :layout] } + !@_content_for.key?(name) && @_proc_for_layout || @_default_layout + end + def _render_template(template, local_assigns = {}) with_template(template) do _evaluate_assigns_and_ivars template.render(self, local_assigns) do |*names| - if !@_content_for.key?(names.first) && @_proc_for_layout - capture(*names, &@_proc_for_layout) - elsif content = @_content_for[names.first || :layout] - content - end + capture(*names, &layout_proc(names.first)) end end rescue Exception => e -- cgit v1.2.3