# This is what every "RTML Helper" ends up instantiating -- eventually. # # The process of loading an RTML helper actually begins in +Rtml::Controller::RtmlHelpers+, which loads the relevant # helpers after being included into a descendant of +ActionController::Base+. After finding the helpers and loading # them, the helpers themselves invoke +Rtml::actions_for+, which analyzes the methods they define and adds them to # an instance of Rtml::Controller::DocumentGenerator. It is at this time that default actions are created in the # controller, where they haven't already been defined, which proxy the actions into a call to # # "render :rtml_helpers => {method_name}" # # - where {method_name} is the name of a given RTML Helper method (also called an RTML Action). # module Rtml::Controller::DocumentGenerator def generate_rtml_helpers(base) base.instance_eval do def hidden_action?(*names) !names.select { |name| hidden_actions.include?(name) }.empty? end def hidden_actions @hidden_actions ||= [] end def hide_action(*names) hidden_actions.concat names.flatten end end base.class_eval do attr_reader :controller delegate :rtml_document, :params, :url_for, :expires_at, :to => :controller delegate :rtml_actions, :to => 'self.class' def initialize(controller) @controller = controller end def respond_to?(name, *args, &block) return super || rtml_document.respond_to?(name, *args, &block) end def method_missing(name, *args, &block) rtml_document.copy_ivars_from(self) rtml_document.send(name, *args, &block) rescue raise $!, $!.message, caller end def fire_action(action_name) copy_ivars_from(controller) # Give rtml actions access to the controller's view helpers (class << self; self; end).send(:include, controller.response.template.helpers) __send__(action_name) end def copy_ivars_from(source) ivars = source.instance_variables ivars -= source.protected_instance_variables if source.respond_to?(:protected_instance_variables) ivars -= source.rtml_protected_instance_variables if source.respond_to?(:rtml_protected_instance_variables) ivars.each { |ivar| instance_variable_set(ivar, source.instance_variable_get(ivar)) } rtml_document.copy_ivars_from(self) end hide_action :initialize, :method_missing, :respond_to?, :copy_ivars_from end base end end