diff options
author | José Valim <jose.valim@gmail.com> | 2010-03-08 11:32:01 +0100 |
---|---|---|
committer | José Valim <jose.valim@gmail.com> | 2010-03-08 11:32:01 +0100 |
commit | 0a85380966e47a38292242e6c3b259d77c738ab5 (patch) | |
tree | 60945065b107368e6cd2f06b63cf40d16f6e88ac | |
parent | 34b2180451f842b180dd925bab10e8f4afa34490 (diff) | |
download | rails-0a85380966e47a38292242e6c3b259d77c738ab5.tar.gz rails-0a85380966e47a38292242e6c3b259d77c738ab5.tar.bz2 rails-0a85380966e47a38292242e6c3b259d77c738ab5.zip |
Finally moved the find template logic to the views.
-rw-r--r-- | actionpack/lib/abstract_controller/layouts.rb | 7 | ||||
-rw-r--r-- | actionpack/lib/abstract_controller/rendering.rb | 232 | ||||
-rw-r--r-- | actionpack/lib/action_controller/metal/compatibility.rb | 11 | ||||
-rw-r--r-- | actionpack/lib/action_controller/metal/implicit_render.rb | 2 | ||||
-rw-r--r-- | actionpack/lib/action_controller/metal/rendering.rb | 41 | ||||
-rw-r--r-- | actionpack/lib/action_view/render/rendering.rb | 40 | ||||
-rw-r--r-- | actionpack/lib/action_view/template/text.rb | 7 | ||||
-rw-r--r-- | actionpack/test/abstract/abstract_controller_test.rb | 4 |
8 files changed, 152 insertions, 192 deletions
diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb index 648a2da795..6ac3806149 100644 --- a/actionpack/lib/abstract_controller/layouts.rb +++ b/actionpack/lib/abstract_controller/layouts.rb @@ -264,7 +264,7 @@ module AbstractController self.class_eval <<-RUBY, __FILE__, __LINE__ + 1 def _layout - if template_exists?("#{_implied_layout_name}", :_prefix => #{_prefix.inspect}) + if template_exists?("#{_implied_layout_name}", #{_prefix.inspect}) "#{_implied_layout_name}" else super @@ -277,7 +277,9 @@ module AbstractController end end - def render_to_body(options) + def _normalize_options(options) + super + if _include_layout?(options) layout = options.key?(:layout) ? options[:layout] : :default value = _layout_for_option(layout) @@ -288,7 +290,6 @@ module AbstractController # TODO Revisit this. :layout with :partial from controllers are not the same as in views options[:layout] = view_context._find_layout(options[:layout]) if options.key?(:partial) end - super end private diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index 9093e90c97..d9087ce294 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -10,7 +10,7 @@ module AbstractController end end - module Rendering + module ViewPaths extend ActiveSupport::Concern included do @@ -21,21 +21,87 @@ module AbstractController delegate :formats, :formats=, :to => :template_lookup delegate :_view_paths, :to => :'self.class' + def template_lookup + @template_lookup ||= ActionView::Template::Lookup.new(_view_paths, details_for_lookup) + end + + def details_for_lookup + { } + end + + # The list of view paths for this controller. See ActionView::ViewPathSet for + # more details about writing custom view paths. + def view_paths + template_lookup.view_paths + end + + def append_view_path(path) + template_lookup.view_paths.push(*path) + end + + def prepend_view_path(path) + template_lookup.view_paths.unshift(*path) + end + + protected + + def template_exists?(*args) + template_lookup.exists?(*args) + end + + def find_template(*args) + template_lookup.find(*args) + end + + module ClassMethods + # Append a path to the list of view paths for this controller. + # + # ==== Parameters + # path<String, ViewPath>:: If a String is provided, it gets converted into + # the default view path. You may also provide a custom view path + # (see ActionView::ViewPathSet for more information) + def append_view_path(path) + self.view_paths = view_paths.dup + Array(path) + end + + # Prepend a path to the list of view paths for this controller. + # + # ==== Parameters + # path<String, ViewPath>:: If a String is provided, it gets converted into + # the default view path. You may also provide a custom view path + # (see ActionView::ViewPathSet for more information) + def prepend_view_path(path) + self.view_paths = Array(path) + view_paths.dup + end + + # A list of all of the default view paths for this controller. + def view_paths + _view_paths + end + + # Set the view paths. + # + # ==== Parameters + # paths<ViewPathSet, Object>:: If a ViewPathSet is provided, use that; + # otherwise, process the parameter into a ViewPathSet. + def view_paths=(paths) + self._view_paths = paths.is_a?(ActionView::PathSet) ? paths : ActionView::Base.process_view_paths(paths) + self._view_paths.freeze + end + end + end + + module Rendering + extend ActiveSupport::Concern + include AbstractController::ViewPaths + # An instance of a view class. The default view class is ActionView::Base # # The view class must have the following methods: - # View.for_controller[controller] Create a new ActionView instance for a - # controller - # View#render_partial[options] - # - responsible for setting options[:_template] - # - Returns String with the rendered partial - # options<Hash>:: see _render_partial in ActionView::Base - # View#render_template[template, layout, options, partial] - # - Returns String with the rendered template - # template<ActionView::Template>:: The template to render - # layout<ActionView::Template>:: The layout to render around the template - # options<Hash>:: See _render_template_with_layout in ActionView::Base - # partial<Boolean>:: Whether or not the template to render is a partial + # View.for_controller[controller] + # Create a new ActionView instance for a controller + # View#render_template[options] + # Returns String with the rendered template # # Override this method in a module to change the default behavior. def view_context @@ -51,64 +117,23 @@ module AbstractController end # Raw rendering of a template to a Rack-compatible body. - # - # ==== Options - # _partial_object<Object>:: The object that is being rendered. If this - # exists, we are in the special case of rendering an object as a partial. - # # :api: plugin def render_to_body(options = {}) - # TODO: Refactor so we can just use the normal template logic for this - if options.key?(:partial) - _render_partial(options) - else - _determine_template(options) - _render_template(options) - end + _process_options(options) + _render_template(options) end # Raw rendering of a template to a string. Just convert the results of # render_to_body into a String. - # # :api: plugin def render_to_string(options={}) _normalize_options(options) AbstractController::Rendering.body_to_s(render_to_body(options)) end - # Renders the template from an object. - # - # ==== Options - # _template<ActionView::Template>:: The template to render - # _layout<ActionView::Template>:: The layout to wrap the template in (optional) + # Find and renders a template based on the options given. def _render_template(options) - view_context.render_template(options) - end - - # Renders the given partial. - # - # ==== Options - # partial<String|Object>:: The partial name or the object to be rendered - def _render_partial(options) - view_context.render_partial(options) - end - - def template_lookup - @template_lookup ||= ActionView::Template::Lookup.new(_view_paths, details_for_render) - end - - # The list of view paths for this controller. See ActionView::ViewPathSet for - # more details about writing custom view paths. - def view_paths - template_lookup.view_paths - end - - def append_view_path(path) - template_lookup.view_paths.push(*path) - end - - def prepend_view_path(path) - template_lookup.view_paths.unshift(*path) + view_context.render_template(options) { |template| _with_template_hook(template) } end # The prefix used in render "foo" shortcuts. @@ -134,59 +159,40 @@ module AbstractController # and render "/foo" to render :file => "/foo". def _normalize_args(action=nil, options={}) case action + when NilClass when Hash options, action = action, nil when String, Symbol action = action.to_s case action.index("/") when NilClass - options[:_prefix] = _prefix - options[:_template_name] = action + options[:action] = action when 0 options[:file] = action else options[:template] = action end + else + options.merge!(:partial => action) end options end def _normalize_options(options) - end + if options[:partial] == true + options[:partial] = action_name + end - # Take in a set of options and determine the template to render - # - # ==== Options - # _template<ActionView::Template>:: If this is provided, the search is over - # _template_name<#to_s>:: The name of the template to look up. Otherwise, - # use the current action name. - # _prefix<String>:: The prefix to look inside of. In a file system, this corresponds - # to a directory. - # _partial<TrueClass, FalseClass>:: Whether or not the file to look up is a partial - def _determine_template(options) - if options.key?(:text) - options[:_template] = ActionView::Template::Text.new(options[:text], format_for_text) - elsif options.key?(:inline) - handler = ActionView::Template.handler_class_for_extension(options[:type] || "erb") - template = ActionView::Template.new(options[:inline], "inline template", handler, {}) - options[:_template] = template - elsif options.key?(:template) - options[:_template_name] = options[:template] - elsif options.key?(:file) - options[:_template_name] = options[:file] + if (options.keys & [:partial, :file, :template]).empty? + options[:_prefix] ||= _prefix end - name = (options[:_template_name] || options[:action] || action_name).to_s - options[:_prefix] ||= _prefix if (options.keys & [:partial, :file, :template]).empty? + + options[:template] ||= (options[:action] || action_name).to_s details = _normalize_details(options) template_lookup.details = details - - options[:_template] ||= find_template(name, options) - end - - def details_for_render - { } + options end def _normalize_details(options) @@ -196,53 +202,11 @@ module AbstractController details end - def find_template(name, options) - template_lookup.find(name, options[:_prefix], options[:_partial]) - end - - def template_exists?(name, options) - template_lookup.exists?(name, options[:_prefix], options[:_partial]) - end - - def format_for_text - Mime[:text] + def _process_options(options) end - module ClassMethods - # Append a path to the list of view paths for this controller. - # - # ==== Parameters - # path<String, ViewPath>:: If a String is provided, it gets converted into - # the default view path. You may also provide a custom view path - # (see ActionView::ViewPathSet for more information) - def append_view_path(path) - self.view_paths = view_paths.dup + Array(path) - end - - # Prepend a path to the list of view paths for this controller. - # - # ==== Parameters - # path<String, ViewPath>:: If a String is provided, it gets converted into - # the default view path. You may also provide a custom view path - # (see ActionView::ViewPathSet for more information) - def prepend_view_path(path) - self.view_paths = Array(path) + view_paths.dup - end - - # A list of all of the default view paths for this controller. - def view_paths - _view_paths - end - - # Set the view paths. - # - # ==== Parameters - # paths<ViewPathSet, Object>:: If a ViewPathSet is provided, use that; - # otherwise, process the parameter into a ViewPathSet. - def view_paths=(paths) - self._view_paths = paths.is_a?(ActionView::PathSet) ? paths : ActionView::Base.process_view_paths(paths) - self._view_paths.freeze - end + def _with_template_hook(template) + self.formats = template.details[:formats] end end end diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index 0cb20b2f0f..5cad0814ca 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -49,14 +49,19 @@ module ActionController super end - def render_to_body(options) - if options.is_a?(Hash) && options.key?(:template) - options[:template].sub!(/^\//, '') + def _normalize_options(options) + # TODO Deprecate this. Rails 2.x allowed to give a template as action. + if options[:action] && options[:action].to_s.include?(?/) + options[:template] = options.delete(:action) end options[:text] = nil if options.delete(:nothing) == true options[:text] = " " if options.key?(:text) && options[:text].nil? + super + end + def render_to_body(options) + options[:template].sub!(/^\//, '') if options.key?(:template) super || " " end diff --git a/actionpack/lib/action_controller/metal/implicit_render.rb b/actionpack/lib/action_controller/metal/implicit_render.rb index c3e3b8fdf5..282dcf66b3 100644 --- a/actionpack/lib/action_controller/metal/implicit_render.rb +++ b/actionpack/lib/action_controller/metal/implicit_render.rb @@ -12,7 +12,7 @@ module ActionController def method_for_action(action_name) super || begin - if template_exists?(action_name.to_s, :_prefix => controller_path) + if template_exists?(action_name.to_s, _prefix) "default_render" end end diff --git a/actionpack/lib/action_controller/metal/rendering.rb b/actionpack/lib/action_controller/metal/rendering.rb index 60d61999de..f892bd9b91 100644 --- a/actionpack/lib/action_controller/metal/rendering.rb +++ b/actionpack/lib/action_controller/metal/rendering.rb @@ -6,46 +6,20 @@ module ActionController include AbstractController::Rendering def process(*) - self.formats = request.formats.map {|x| x.to_sym } + self.formats = request.formats.map { |x| x.to_sym } super end def render(*args) raise ::AbstractController::DoubleRenderError if response_body - args << {} unless args.last.is_a?(Hash) - super(*args) - self.content_type ||= args.last[:_template].mime_type.to_s - response_body - end - - def render_to_body(options) - _process_options(options) super + response_body end private - def _render_partial(options) - options[:partial] = action_name if options[:partial] == true - options[:_details] = details_for_render - super - end - - def format_for_text - formats.first - end - def _normalize_args(action=nil, options={}, &blk) - case action - when NilClass - when Hash - options = super(action.delete(:action), action) - when String, Symbol - options = super - else - options.merge!(:partial => action) - end - + options = super options[:update] = blk if block_given? options end @@ -64,9 +38,18 @@ module ActionController def _process_options(options) status, content_type, location = options.values_at(:status, :content_type, :location) + self.status = status if status self.content_type = content_type if content_type self.headers["Location"] = url_for(location) if location + + super end + + def _with_template_hook(template) + super + self.content_type ||= template.mime_type.to_s + end + end end diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb index 17fb110eb4..c6d95e88e2 100644 --- a/actionpack/lib/action_view/render/rendering.rb +++ b/actionpack/lib/action_view/render/rendering.rb @@ -24,18 +24,8 @@ module ActionView return _render_partial(options) end - template = if options[:file] - find(options[:file]) - elsif options[:inline] - handler = Template.handler_class_for_extension(options[:type] || "erb") - Template.new(options[:inline], "inline template", handler, {}) - elsif options[:text] - Template::Text.new(options[:text]) - end - - if template - _render_template(template, layout, :locals => options[:locals]) - end + template = _determine_template(options) + _render_template(template, layout, :locals => options[:locals]) if template when :update update_page(&block) else @@ -87,8 +77,28 @@ module ActionView # _layout:: The layout, if any, to wrap the Template in def render_template(options) _evaluate_assigns_and_ivars - template, layout = options.values_at(:_template, :layout) - _render_template(template, layout, options) + if options.key?(:partial) + _render_partial(options) + else + template = _determine_template(options) + yield template if block_given? + _render_template(template, options[:layout], options) + end + end + + def _determine_template(options) + if options.key?(:inline) + handler = Template.handler_class_for_extension(options[:type] || "erb") + Template.new(options[:inline], "inline template", handler, {}) + elsif options.key?(:text) + Template::Text.new(options[:text], self.formats.try(:first)) + elsif options.key?(:_template) + options[:_template] + elsif options.key?(:file) + find(options[:file], options[:_prefix]) + elsif options.key?(:template) + find(options[:template], options[:_prefix]) + end end def _find_layout(layout) @@ -102,8 +112,6 @@ module ActionView end def _render_template(template, layout = nil, options = {}) - self.formats = template.details[:formats] - locals = options[:locals] || {} layout = _find_layout(layout) if layout diff --git a/actionpack/lib/action_view/template/text.rb b/actionpack/lib/action_view/template/text.rb index 2abb352d4e..5978a8a3ac 100644 --- a/actionpack/lib/action_view/template/text.rb +++ b/actionpack/lib/action_view/template/text.rb @@ -1,11 +1,10 @@ module ActionView #:nodoc: class Template class Text < String #:nodoc: - HTML = Mime[:html] - - def initialize(string, content_type = HTML) + def initialize(string, content_type = nil) super(string.to_s) - @content_type = Mime[content_type] || content_type + @content_type = Mime[content_type] || content_type if content_type + @content_type ||= Mime::TEXT end def details diff --git a/actionpack/test/abstract/abstract_controller_test.rb b/actionpack/test/abstract/abstract_controller_test.rb index 4ad87d9762..f70d497481 100644 --- a/actionpack/test/abstract/abstract_controller_test.rb +++ b/actionpack/test/abstract/abstract_controller_test.rb @@ -59,11 +59,11 @@ module AbstractController end def rendering_to_body - self.response_body = render_to_body :_template_name => "naked_render.erb" + self.response_body = render_to_body :template => "naked_render.erb" end def rendering_to_string - self.response_body = render_to_string :_template_name => "naked_render.erb" + self.response_body = render_to_string :template => "naked_render.erb" end end |