From 0a85380966e47a38292242e6c3b259d77c738ab5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 8 Mar 2010 11:32:01 +0100 Subject: Finally moved the find template logic to the views. --- actionpack/lib/abstract_controller/layouts.rb | 7 +- actionpack/lib/abstract_controller/rendering.rb | 232 ++++++++++-------------- 2 files changed, 102 insertions(+), 137 deletions(-) (limited to 'actionpack/lib/abstract_controller') 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:: 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:: 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:: 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:: see _render_partial in ActionView::Base - # View#render_template[template, layout, options, partial] - # - Returns String with the rendered template - # template:: The template to render - # layout:: The layout to render around the template - # options:: See _render_template_with_layout in ActionView::Base - # partial:: 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:: 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:: The template to render - # _layout:: 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:: 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:: 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:: The prefix to look inside of. In a file system, this corresponds - # to a directory. - # _partial:: 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:: 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:: 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:: 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 -- cgit v1.2.3