X-Git-Url: https://git.njae.me.uk/?a=blobdiff_plain;f=vendor%2Frails%2Factionpack%2Flib%2Faction_controller%2Fcomponents.rb;fp=vendor%2Frails%2Factionpack%2Flib%2Faction_controller%2Fcomponents.rb;h=f446b91e7eab55b63472df1d7794555a602382c9;hb=d115f2e23823271635bad69229a42cd8ac68debe;hp=0000000000000000000000000000000000000000;hpb=37cb670bf3ddde90b214e591f100ed4446469484;p=depot.git diff --git a/vendor/rails/actionpack/lib/action_controller/components.rb b/vendor/rails/actionpack/lib/action_controller/components.rb new file mode 100644 index 0000000..f446b91 --- /dev/null +++ b/vendor/rails/actionpack/lib/action_controller/components.rb @@ -0,0 +1,169 @@ +module ActionController #:nodoc: + # Components allow you to call other actions for their rendered response while executing another action. You can either delegate + # the entire response rendering or you can mix a partial response in with your other content. + # + # class WeblogController < ActionController::Base + # # Performs a method and then lets hello_world output its render + # def delegate_action + # do_other_stuff_before_hello_world + # render_component :controller => "greeter", :action => "hello_world", :params => { :person => "david" } + # end + # end + # + # class GreeterController < ActionController::Base + # def hello_world + # render :text => "#{params[:person]} says, Hello World!" + # end + # end + # + # The same can be done in a view to do a partial rendering: + # + # Let's see a greeting: + # <%= render_component :controller => "greeter", :action => "hello_world" %> + # + # It is also possible to specify the controller as a class constant, bypassing the inflector + # code to compute the controller class at runtime: + # + # <%= render_component :controller => GreeterController, :action => "hello_world" %> + # + # == When to use components + # + # Components should be used with care. They're significantly slower than simply splitting reusable parts into partials and + # conceptually more complicated. Don't use components as a way of separating concerns inside a single application. Instead, + # reserve components to those rare cases where you truly have reusable view and controller elements that can be employed + # across many applications at once. + # + # So to repeat: Components are a special-purpose approach that can often be replaced with better use of partials and filters. + module Components + def self.included(base) #:nodoc: + base.class_eval do + include InstanceMethods + include ActiveSupport::Deprecation + extend ClassMethods + helper HelperMethods + + # If this controller was instantiated to process a component request, + # +parent_controller+ points to the instantiator of this controller. + attr_accessor :parent_controller + + alias_method_chain :process_cleanup, :components + alias_method_chain :set_session_options, :components + alias_method_chain :flash, :components + + alias_method :component_request?, :parent_controller + end + end + + module ClassMethods + # Track parent controller to identify component requests + def process_with_components(request, response, parent_controller = nil) #:nodoc: + controller = new + controller.parent_controller = parent_controller + controller.process(request, response) + end + end + + module HelperMethods + def render_component(options) + @controller.__send__(:render_component_as_string, options) + end + end + + module InstanceMethods + # Extracts the action_name from the request parameters and performs that action. + def process_with_components(request, response, method = :perform_action, *arguments) #:nodoc: + flash.discard if component_request? + process_without_components(request, response, method, *arguments) + end + + protected + # Renders the component specified as the response for the current method + def render_component(options) #:doc: + component_logging(options) do + render_for_text(component_response(options, true).body, response.headers["Status"]) + end + end + deprecate :render_component => "Please install render_component plugin from http://github.com/rails/render_component/tree/master" + + # 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 + deprecate :render_component_as_string => "Please install render_component plugin from http://github.com/rails/render_component/tree/master" + + def flash_with_components(refresh = false) #:nodoc: + if !defined?(@_flash) || refresh + @_flash = + if defined?(@parent_controller) + @parent_controller.flash + else + flash_without_components + end + end + @_flash + end + + private + def component_response(options, reuse_response) + klass = component_class(options) + request = request_for_component(klass.controller_name, options) + new_response = reuse_response ? response : response.dup + + klass.process_with_components(request, new_response, self) + end + + # determine the controller class for the component request + def component_class(options) + if controller = options[:controller] + controller.is_a?(Class) ? controller : "#{controller.camelize}Controller".constantize + 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) + new_request = request.dup + new_request.session = request.session + + new_request.instance_variable_set( + :@parameters, + (options[:params] || {}).with_indifferent_access.update( + "controller" => controller_name, "action" => options[:action], "id" => options[:id] + ) + ) + + new_request + end + + def component_logging(options) + if logger + logger.info "Start rendering component (#{options.inspect}): " + result = yield + logger.info "\n\nEnd of component rendering" + result + else + yield + end + end + + def set_session_options_with_components(request) + set_session_options_without_components(request) unless component_request? + end + + def process_cleanup_with_components + process_cleanup_without_components unless component_request? + end + end + end +end