提交 367bdc53 编写于 作者: J José Valim

Remove view dependency from AV::Renderer.

上级 33cc001f
......@@ -35,6 +35,7 @@ module ActionView
autoload :Helpers
autoload :LookupContext
autoload :PathSet
autoload :Rendering
autoload :Template
autoload :TestCase
......
......@@ -131,7 +131,7 @@ module ActionView #:nodoc:
#
# More builder documentation can be found at http://builder.rubyforge.org.
class Base
include Helpers, ::ERB::Util, Context
include Helpers, Rendering, ::ERB::Util, Context
# Specify the proc used to decorate input tags that refer to attributes with errors.
cattr_accessor :field_error_proc
......@@ -162,7 +162,7 @@ def cache_template_loading=(value)
attr_accessor :view_renderer
attr_internal :request, :controller, :config, :assigns
delegate :lookup_context, :render, :render_body, :to => :view_renderer
delegate :lookup_context, :to => :view_renderer
delegate :formats, :formats=, :locale, :locale=, :view_paths, :view_paths=, :to => :lookup_context
delegate :request_forgery_protection_token, :params, :session, :cookies, :response, :headers,
......@@ -183,10 +183,11 @@ def assign(new_assigns) # :nodoc:
@_assigns = new_assigns.each { |key, value| instance_variable_set("@#{key}", value) }
end
def initialize(lookup_context = nil, assigns_for_first_render = {}, controller = nil, formats = nil) #:nodoc:
def initialize(context = nil, assigns_for_first_render = {}, controller = nil, formats = nil) #: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
......@@ -197,13 +198,19 @@ def initialize(lookup_context = nil, assigns_for_first_render = {}, controller =
@_config = controller.config.inheritable_copy if controller.respond_to?(:config)
end
_lookup_context = lookup_context.is_a?(ActionView::LookupContext) ?
lookup_context : ActionView::LookupContext.new(lookup_context)
_lookup_context.formats = formats if formats
@view_renderer = ActionView::Renderer.new(_lookup_context, self)
# Handle all these for backwards compatibility.
# TODO Provide a new API for AV::Base and deprecate this one.
if context.is_a?(ActionView::Renderer)
@view_renderer = context
elsif
lookup_context = context.is_a?(ActionView::LookupContext) ?
context : ActionView::LookupContext.new(context)
lookup_context.formats = formats if formats
@view_renderer = ActionView::Renderer.new(lookup_context, controller)
end
end
# TODO Is this needed anywhere? Maybe deprecate it?
def controller_path
@controller_path ||= controller && controller.controller_path
end
......
......@@ -3,9 +3,9 @@ class AbstractRenderer #:nodoc:
delegate :find_template, :template_exists?, :with_fallbacks, :update_details,
:with_layout_format, :formats, :freeze_formats, :to => :@lookup_context
def initialize(view, lookup_context)
@view = view
def initialize(lookup_context, controller)
@lookup_context = lookup_context
@controller = controller
end
def render
......
......@@ -217,45 +217,14 @@ module ActionView
class PartialRenderer < AbstractRenderer #:nodoc:
PARTIAL_NAMES = Hash.new {|h,k| h[k] = {} }
# TODO Controller should not come from the view
def initialize(view, *)
def initialize(*)
super
@controller = @view.controller
@partial_names = PARTIAL_NAMES[@controller.class.name]
end
def setup(options, block)
partial = options[:partial]
@options = options
@locals = options[:locals] || {}
@block = block
if String === partial
@object = options[:object]
@path = partial
@collection = collection
else
@object = partial
if @collection = collection_from_object || collection
paths = @collection_data = @collection.map { |o| partial_path(o) }
@path = paths.uniq.size == 1 ? paths.first : nil
else
@path = partial_path
end
end
def render(context, options, block)
setup(context, options, block)
if @path
@variable, @variable_counter = retrieve_variable(@path)
else
paths.map! { |path| retrieve_variable(path).unshift(path) }
end
self
end
def render
wrap_formats(@path) do
identifier = ((@template = find_partial) ? @template.identifier : @path)
......@@ -303,6 +272,38 @@ def render_partial
private
def setup(context, options, block)
@view = context
partial = options[:partial]
@options = options
@locals = options[:locals] || {}
@block = block
if String === partial
@object = options[:object]
@path = partial
@collection = collection
else
@object = partial
if @collection = collection_from_object || collection
paths = @collection_data = @collection.map { |o| partial_path(o) }
@path = paths.uniq.size == 1 ? paths.first : nil
else
@path = partial_path
end
end
if @path
@variable, @variable_counter = retrieve_variable(@path)
else
paths.map! { |path| retrieve_variable(path).unshift(path) }
end
self
end
def controller_prefixes
@controller_prefixes ||= @controller && @controller._prefixes
end
......
......@@ -3,37 +3,25 @@ module ActionView
# to other objects like TemplateRenderer and PartialRenderer which
# actually renders the template.
class Renderer
attr_accessor :lookup_context
attr_accessor :lookup_context, :controller
# TODO: render_context should not be an initialization parameter
# TODO: controller should be received on initialization
def initialize(lookup_context, render_context)
@render_context = render_context
def initialize(lookup_context, controller)
@lookup_context = lookup_context
@view_flow = OutputFlow.new
@controller = controller
end
# 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(context, options = {}, locals = {}, &block)
case options
when Hash
if block_given?
_render_partial(options.merge(:partial => options[:layout]), &block)
_render_partial(context, options.merge(:partial => options[:layout]), &block)
elsif options.key?(:partial)
_render_partial(options)
_render_partial(context, options)
else
_render_template(options)
_render_template(context, options)
end
else
_render_partial(:partial => options, :locals => locals)
_render_partial(context, :partial => options, :locals => locals)
end
end
......@@ -42,30 +30,30 @@ def render(options = {}, locals = {}, &block)
#
# Note that partials are not supported to be rendered with streaming,
# so in such cases, we just wrap them in an array.
def render_body(options)
def render_body(context, options)
if options.key?(:partial)
[_render_partial(options)]
[_render_partial(context, options)]
else
StreamingTemplateRenderer.new(@render_context, @lookup_context).render(options)
StreamingTemplateRenderer.new(@lookup_context, @controller).render(context, options)
end
end
private
def _render_template(options) #:nodoc:
_template_renderer.render(options)
def _render_template(context, options) #:nodoc:
_template_renderer.render(context, options)
end
def _template_renderer #:nodoc:
@_template_renderer ||= TemplateRenderer.new(@render_context, @lookup_context)
@_template_renderer ||= TemplateRenderer.new(@lookup_context, @controller)
end
def _render_partial(options, &block) #:nodoc:
_partial_renderer.setup(options, block).render
def _render_partial(context, options, &block) #:nodoc:
_partial_renderer.render(context, options, block)
end
def _partial_renderer #:nodoc:
@_partial_renderer ||= PartialRenderer.new(@render_context, @lookup_context)
@_partial_renderer ||= PartialRenderer.new(@lookup_context, @controller)
end
end
end
\ No newline at end of file
......@@ -3,7 +3,9 @@
module ActionView
class TemplateRenderer < AbstractRenderer #:nodoc:
def render(options)
def render(context, options)
@view = context
wrap_formats(options[:template] || options[:file]) do
template = determine_template(options)
freeze_formats(template.formats, true)
......
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(*args, &block)
view_renderer.render(self, *args, &block)
end
# TODO: This is temporary, but the previous render is sticking.
def render_body(*args, &block)
view_renderer.render_body(self, *args, &block)
end
end
end
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册