From 137794310b02840773213c81c86411b43935db90 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sun, 12 Feb 2006 00:46:01 +0000 Subject: The components module should also contain the options that pertain to it, so collect it all with ClassMethods and InstanceMethods git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@3576 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- actionpack/lib/action_controller/base.rb | 21 +---- actionpack/lib/action_controller/components.rb | 126 ++++++++++++++----------- 2 files changed, 77 insertions(+), 70 deletions(-) diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index b92dd1ca4e..50fded00c5 100755 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -305,7 +305,7 @@ module ActionController #:nodoc: class << self # Factory for the standard create, process loop where the controller is discarded after processing. - def process(request, response, parent_controller=nil) #:nodoc: + def process(request, response, parent_controller = nil) #:nodoc: new(parent_controller).process(request, response) end @@ -328,12 +328,13 @@ module ActionController #:nodoc: components.shift if components.first == 'Controllers' @controller_path = components.map { |name| name.underscore }.join('/') end + @controller_path end # Return an array containing the names of public methods that have been marked hidden from the action processor. # By default, all methods defined in ActionController::Base and included modules are hidden. - # More methods can be hidden using +hide_actions+. + # More methods can be hidden using hide_actions. def hidden_actions write_inheritable_attribute(:hidden_actions, ActionController::Base.public_instance_methods) unless read_inheritable_attribute(:hidden_actions) read_inheritable_attribute(:hidden_actions) @@ -341,21 +342,7 @@ module ActionController #:nodoc: # Hide each of the given methods from being callable as actions. def hide_action(*names) - write_inheritable_attribute(:hidden_actions, hidden_actions | names.collect {|n| n.to_s}) - end - - # Set the template root to be one directory behind the root dir of the controller. Examples: - # /code/weblog/components/admin/users_controller.rb with Admin::UsersController - # will use /code/weblog/components as template root - # and find templates in /code/weblog/components/admin/users/ - # - # /code/weblog/components/admin/parties/users_controller.rb with Admin::Parties::UsersController - # will also use /code/weblog/components as template root - # and find templates in /code/weblog/components/admin/parties/users/ - def uses_component_template_root - path_of_calling_controller = File.dirname(caller[0].split(/:\d+:/).first) - path_of_controller_root = path_of_calling_controller.sub(/#{controller_path.split("/")[0..-2]}$/, "") # " (for ruby-mode) - self.template_root = path_of_controller_root + write_inheritable_attribute(:hidden_actions, hidden_actions | names.collect { |n| n.to_s }) end end diff --git a/actionpack/lib/action_controller/components.rb b/actionpack/lib/action_controller/components.rb index 7cbbe3edd2..ba08670610 100644 --- a/actionpack/lib/action_controller/components.rb +++ b/actionpack/lib/action_controller/components.rb @@ -28,8 +28,10 @@ module ActionController #:nodoc: # # would work as well and be slightly faster. module Components - def self.append_features(base) #:nodoc: - super + def self.included(base) #:nodoc: + base.extend(ClassMethods) + base.send(:include, InstanceMethods) + base.helper do def render_component(options) @controller.send(:render_component_as_string, options) @@ -37,68 +39,86 @@ module ActionController #:nodoc: end end - protected - # Renders the component specified as the response for the current method - def render_component(options) #:doc: - component_logging(options) do - render_text(component_response(options, true).body, response.headers["Status"]) - end + module ClassMethods + # Set the template root to be one directory behind the root dir of the controller. Examples: + # /code/weblog/components/admin/users_controller.rb with Admin::UsersController + # will use /code/weblog/components as template root + # and find templates in /code/weblog/components/admin/users/ + # + # /code/weblog/components/admin/parties/users_controller.rb with Admin::Parties::UsersController + # will also use /code/weblog/components as template root + # and find templates in /code/weblog/components/admin/parties/users/ + def uses_component_template_root + path_of_calling_controller = File.dirname(caller[0].split(/:\d+:/).first) + path_of_controller_root = path_of_calling_controller.sub(/#{controller_path.split("/")[0..-2]}$/, "") # " (for ruby-mode) + self.template_root = path_of_controller_root end + end - # Returns the component response as a string - def render_component_as_string(options) #:doc: - component_logging(options) do - response = component_response(options, false) - if redirected = response.redirected_to - render_component_as_string redirected - else - response.body + module InstanceMethods + protected + # Renders the component specified as the response for the current method + def render_component(options) #:doc: + component_logging(options) do + render_text(component_response(options, true).body, response.headers["Status"]) end - end - end + end + + # Returns the component response as a string + def render_component_as_string(options) #:doc: + component_logging(options) do + response = component_response(options, false) + if redirected = response.redirected_to + render_component_as_string redirected + else + response.body + end + end + end - private - def component_response(options, reuse_response) - c_class = component_class(options) - c_request = request_for_component(c_class.controller_name, options) - c_response = reuse_response ? @response : @response.dup - c_class.process(c_request, c_response, self) - end + private + def component_response(options, reuse_response) + c_class = component_class(options) + c_request = request_for_component(c_class.controller_name, options) + c_response = reuse_response ? @response : @response.dup + c_class.process(c_request, c_response, self) + end - # determine the controller class for the component request - def component_class(options) - if controller = options[:controller] - if controller.is_a? Class - controller + # determine the controller class for the component request + def component_class(options) + if controller = options[:controller] + if controller.is_a? Class + controller + else + "#{controller.camelize}Controller".constantize + end else - "#{controller.camelize}Controller".constantize + self.class end - else - self.class end - end - # Create a new request object based on the current request. - # The new request inherits the session from the current request, - # bypassing any session options set for the component controller's class - def request_for_component(controller_name, options) - sub_request = @request.dup - sub_request.session = @request.session - sub_request.instance_variable_set(:@parameters, - (options[:params] || {}).with_indifferent_access.regular_update( - "controller" => controller_name, "action" => options[:action], "id" => options[:id]) - ) - sub_request - end + # Create a new request object based on the current request. + # The new request inherits the session from the current request, + # bypassing any session options set for the component controller's class + def request_for_component(controller_name, options) + sub_request = @request.dup + sub_request.session = @request.session + sub_request.instance_variable_set(:@parameters, + (options[:params] || {}).with_indifferent_access.regular_update( + "controller" => controller_name, "action" => options[:action], "id" => options[:id]) + ) + sub_request + end - def component_logging(options) - unless logger then yield else - logger.info("Start rendering component (#{options.inspect}): ") - result = yield - logger.info("\n\nEnd of component rendering") - result + def component_logging(options) + unless logger then yield else + logger.info("Start rendering component (#{options.inspect}): ") + result = yield + logger.info("\n\nEnd of component rendering") + result + end end - end + end end end -- cgit v1.2.3