aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosé Valim <jose.valim@gmail.com>2011-05-01 19:39:57 +0200
committerJosé Valim <jose.valim@gmail.com>2011-05-01 19:39:57 +0200
commit13df194c002f362556560303da9c73a24ebb189e (patch)
treee3eca086931009829feadb10aafdc6d28570c98b
parent8dbee3aba6920edcae20abf3af7f803e528f9ee0 (diff)
downloadrails-13df194c002f362556560303da9c73a24ebb189e.tar.gz
rails-13df194c002f362556560303da9c73a24ebb189e.tar.bz2
rails-13df194c002f362556560303da9c73a24ebb189e.zip
Tidy up pending TODOs after discussion with Mr. Gatoz (@wycats).
-rw-r--r--actionpack/lib/action_view.rb1
-rw-r--r--actionpack/lib/action_view/base.rb9
-rw-r--r--actionpack/lib/action_view/context.rb76
-rw-r--r--actionpack/lib/action_view/helpers.rb2
-rw-r--r--actionpack/lib/action_view/helpers/rendering_helper.rb92
-rw-r--r--actionpack/lib/action_view/rendering.rb33
-rw-r--r--actionpack/test/controller/new_base/render_context_test.rb14
7 files changed, 120 insertions, 107 deletions
diff --git a/actionpack/lib/action_view.rb b/actionpack/lib/action_view.rb
index 69c50a056c..92b6f7c770 100644
--- a/actionpack/lib/action_view.rb
+++ b/actionpack/lib/action_view.rb
@@ -35,7 +35,6 @@ module ActionView
autoload :Helpers
autoload :LookupContext
autoload :PathSet
- autoload :Rendering
autoload :Template
autoload :TestCase
diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb
index baa2c5729f..ca0a89c8a5 100644
--- a/actionpack/lib/action_view/base.rb
+++ b/actionpack/lib/action_view/base.rb
@@ -131,7 +131,7 @@ module ActionView #:nodoc:
#
# More builder documentation can be found at http://builder.rubyforge.org.
class Base
- include Helpers, Rendering, ::ERB::Util, Context
+ include Helpers, ::ERB::Util, Context
# Specify the proc used to decorate input tags that refer to attributes with errors.
cattr_accessor :field_error_proc
@@ -186,11 +186,6 @@ module ActionView #:nodoc:
assign(assigns_for_first_render)
self.helpers = Module.new unless self.class.helpers
- # Context vars initialization
- @view_flow = OutputFlow.new
- @output_buffer = nil
- @virtual_path = nil
-
@_config = {}
if @_controller = controller
@_request = controller.request if controller.respond_to?(:request)
@@ -207,6 +202,8 @@ module ActionView #:nodoc:
lookup_context.formats = formats if formats
@view_renderer = ActionView::Renderer.new(lookup_context, controller)
end
+
+ _prepare_context
end
# TODO Is this needed anywhere? Maybe deprecate it?
diff --git a/actionpack/lib/action_view/context.rb b/actionpack/lib/action_view/context.rb
index d501a6eaf9..083856b2ca 100644
--- a/actionpack/lib/action_view/context.rb
+++ b/actionpack/lib/action_view/context.rb
@@ -10,71 +10,27 @@ module ActionView
#
# In order to work with ActionController, a Context must just include this module.
# The initialization of the variables used by the context (@output_buffer, @view_flow,
- # and @virtual_path) is responsibility of the object that includes this module.
+ # and @virtual_path) is responsibility of the object that includes this module
+ # (although you can call _prepare_context defined below).
module Context
include CompiledTemplates
attr_accessor :output_buffer, :view_flow
- # TODO Provide an easy method that initializes all variables?
-
- # Returns the contents that are yielded to a layout, given a name or a block.
- #
- # 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>.
- #
- # The user can override this default by passing a block to the layout:
- #
- # # The template
- # <%= render :layout => "my_layout" do %>
- # Content
- # <% end %>
- #
- # # The layout
- # <html>
- # <%= yield %>
- # </html>
- #
- # 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
- #
- # <html>
- # Content
- # </html>
- #
- # Finally, the block can take block arguments, which can be passed in by +yield+:
- #
- # # The template
- # <%= render :layout => "my_layout" do |customer| %>
- # Hello <%= customer.name %>
- # <% end %>
- #
- # # The layout
- # <html>
- # <%= yield Struct.new(:name).new("David") %>
- # </html>
- #
- # In this case, the layout would receive the block passed into <tt>render :layout</tt>,
- # and the struct specified would be passed into the block as an argument. The result
- # would be
- #
- # <html>
- # Hello David
- # </html>
- #
- def _layout_for(*args, &block)
- name = args.first
+ # Prepares the context by setting the appropriate instance variables.
+ # :api: plugin
+ def _prepare_context
+ @view_flow = OutputFlow.new
+ @output_buffer = nil
+ @virtual_path = nil
+ end
- if name.is_a?(Symbol)
- view_flow.get(name).html_safe
- elsif block
- # TODO Import capture into AV::Context or
- # leave it as implicit dependency?
- capture(*args, &block)
- else
- view_flow.get(:layout).html_safe
- end
+ # Encapsulates the interaction with the view flow so it
+ # returns the correct buffer on yield. This is usually
+ # overwriten by helpers to add more behavior.
+ # :api: plugin
+ def _layout_for(name=nil)
+ name ||= :layout
+ view_flow.get(name).html_safe
end
end
end \ No newline at end of file
diff --git a/actionpack/lib/action_view/helpers.rb b/actionpack/lib/action_view/helpers.rb
index 205116f610..3ef9826d30 100644
--- a/actionpack/lib/action_view/helpers.rb
+++ b/actionpack/lib/action_view/helpers.rb
@@ -19,6 +19,7 @@ module ActionView #:nodoc:
autoload :NumberHelper
autoload :OutputSafetyHelper
autoload :RecordTagHelper
+ autoload :RenderingHelper
autoload :SanitizeHelper
autoload :SprocketsHelper
autoload :TagHelper
@@ -48,6 +49,7 @@ module ActionView #:nodoc:
include NumberHelper
include OutputSafetyHelper
include RecordTagHelper
+ include RenderingHelper
include SanitizeHelper
include SprocketsHelper
include TagHelper
diff --git a/actionpack/lib/action_view/helpers/rendering_helper.rb b/actionpack/lib/action_view/helpers/rendering_helper.rb
new file mode 100644
index 0000000000..c91e03b7e8
--- /dev/null
+++ b/actionpack/lib/action_view/helpers/rendering_helper.rb
@@ -0,0 +1,92 @@
+module ActionView
+ module Helpers
+ # = Action View Rendering
+ #
+ # Implements methods that allow rendering from a view context.
+ # In order to use this module, all you need is to implement
+ # view_renderer that returns an ActionView::Renderer object.
+ module RenderingHelper
+ # Returns the result of a render that's dictated by the options hash. The primary options are:
+ #
+ # * <tt>:partial</tt> - See ActionView::Partials.
+ # * <tt>:file</tt> - Renders an explicit template file (this used to be the old default), add :locals to pass in those.
+ # * <tt>:inline</tt> - Renders an inline template similar to how it's done in the controller.
+ # * <tt>:text</tt> - Renders the text passed in out.
+ #
+ # If no options hash is passed or :update specified, the default is to render a partial and use the second parameter
+ # as the locals hash.
+ def render(options = {}, locals = {}, &block)
+ case options
+ when Hash
+ if block_given?
+ view_renderer.render_partial(self, options.merge(:partial => options[:layout]), &block)
+ elsif options.key?(:partial)
+ view_renderer.render_partial(self, options)
+ else
+ view_renderer.render_template(self, options)
+ end
+ else
+ view_renderer.render_partial(self, :partial => options, :locals => locals)
+ end
+ end
+
+ # Overwrites _layout_for in the context object so it supports the case a block is
+ # passed to a partial. Returns the contents that are yielded to a layout, given a
+ # name or a block.
+ #
+ # 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>.
+ #
+ # The user can override this default by passing a block to the layout:
+ #
+ # # The template
+ # <%= render :layout => "my_layout" do %>
+ # Content
+ # <% end %>
+ #
+ # # The layout
+ # <html>
+ # <%= yield %>
+ # </html>
+ #
+ # 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
+ #
+ # <html>
+ # Content
+ # </html>
+ #
+ # Finally, the block can take block arguments, which can be passed in by +yield+:
+ #
+ # # The template
+ # <%= render :layout => "my_layout" do |customer| %>
+ # Hello <%= customer.name %>
+ # <% end %>
+ #
+ # # The layout
+ # <html>
+ # <%= yield Struct.new(:name).new("David") %>
+ # </html>
+ #
+ # In this case, the layout would receive the block passed into <tt>render :layout</tt>,
+ # and the struct specified would be passed into the block as an argument. The result
+ # would be
+ #
+ # <html>
+ # Hello David
+ # </html>
+ #
+ def _layout_for(*args, &block)
+ name = args.first
+
+ if block && !name.is_a?(Symbol)
+ capture(*args, &block)
+ else
+ super
+ end
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/actionpack/lib/action_view/rendering.rb b/actionpack/lib/action_view/rendering.rb
deleted file mode 100644
index 25ec450e6e..0000000000
--- a/actionpack/lib/action_view/rendering.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-module ActionView
- # = Action View Rendering
- #
- # Implements methods that allow rendering from a view context.
- # In order to use this module, all you need is to implement
- # view_renderer that returns an ActionView::Renderer object.
- module Rendering
- # Returns the result of a render that's dictated by the options hash. The primary options are:
- #
- # * <tt>:partial</tt> - See ActionView::Partials.
- # * <tt>:file</tt> - Renders an explicit template file (this used to be the old default), add :locals to pass in those.
- # * <tt>:inline</tt> - Renders an inline template similar to how it's done in the controller.
- # * <tt>:text</tt> - Renders the text passed in out.
- #
- # If no options hash is passed or :update specified, the default is to render a partial and use the second parameter
- # as the locals hash.
- # def render(options = {}, locals = {}, &block)
- def render(options = {}, locals = {}, &block)
- case options
- when Hash
- if block_given?
- view_renderer.render_partial(self, options.merge(:partial => options[:layout]), &block)
- elsif options.key?(:partial)
- view_renderer.render_partial(self, options)
- else
- view_renderer.render_template(self, options)
- end
- else
- view_renderer.render_partial(self, :partial => options, :locals => locals)
- end
- end
- end
-end \ No newline at end of file
diff --git a/actionpack/test/controller/new_base/render_context_test.rb b/actionpack/test/controller/new_base/render_context_test.rb
index 3174bf42ab..f41b14d5d6 100644
--- a/actionpack/test/controller/new_base/render_context_test.rb
+++ b/actionpack/test/controller/new_base/render_context_test.rb
@@ -1,5 +1,8 @@
require 'abstract_unit'
+# This is testing the decoupling of view renderer and view context
+# by allowing the controller to be used as view context. This is
+# similar to the way sinatra renders templates.
module RenderContext
class BasicController < ActionController::Base
self.view_paths = [ActionView::FixtureResolver.new(
@@ -7,15 +10,11 @@ module RenderContext
"layouts/basic.html.erb" => "?<%= yield %>?"
)]
- # Include ViewContext
+ # 1) Include ActionView::Context to bring the required dependencies
include ActionView::Context
- # And initialize the required variables
- before_filter do
- @output_buffer = nil
- @virtual_path = nil
- @view_flow = ActionView::OutputFlow.new
- end
+ # 2) Call _prepare_context that will do the required initialization
+ before_filter :_prepare_context
def hello_world
@value = "Hello"
@@ -29,6 +28,7 @@ module RenderContext
protected
+ # 3) Set view_context to self
def view_context
self
end