diff options
Diffstat (limited to 'actionpack')
4 files changed, 55 insertions, 23 deletions
diff --git a/actionpack/lib/action_controller/abstract/helpers.rb b/actionpack/lib/action_controller/abstract/helpers.rb index 0a2776de9c..6b73f887c1 100644 --- a/actionpack/lib/action_controller/abstract/helpers.rb +++ b/actionpack/lib/action_controller/abstract/helpers.rb @@ -5,33 +5,26 @@ module AbstractController include Renderer included do - extlib_inheritable_accessor :master_helper_module - self.master_helper_module = Module.new + extlib_inheritable_accessor(:_helpers) { Module.new } end + # Override AbstractController::Renderer's _action_view to include the + # helper module for this class into its helpers module. def _action_view - @_action_view ||= begin - av = super - av.helpers.send(:include, master_helper_module) - av - end + @_action_view ||= super.tap { |av| av.helpers.include(_helpers) } end module ClassMethods + # When a class is inherited, wrap its helper module in a new module. + # This ensures that the parent class's module can be changed + # independently of the child class's. def inherited(klass) - klass.master_helper_module = Module.new - klass.master_helper_module.__send__ :include, master_helper_module + helpers = _helpers + klass._helpers = Module.new { include helpers } super end - # Makes all the (instance) methods in the helper module available to templates rendered through this controller. - # See ActionView::Helpers (link:classes/ActionView/Helpers.html) for more about making your own helper modules - # available to the templates. - def add_template_helper(mod) - master_helper_module.module_eval { include mod } - end - # Declare a controller method as a helper. For example, the following # makes the +current_user+ controller method available to the view: # class ApplicationController < ActionController::Base @@ -48,9 +41,13 @@ module AbstractController # # In a view: # <% if logged_in? -%>Welcome, <%= current_user.name %><% end -%> + # + # ==== Parameters + # meths<Array[#to_s]>:: The name of a method on the controller + # to be made available on the view. def helper_method(*meths) meths.flatten.each do |meth| - master_helper_module.class_eval <<-ruby_eval, __FILE__, __LINE__ + 1 + _helpers.class_eval <<-ruby_eval, __FILE__, __LINE__ + 1 def #{meth}(*args, &blk) controller.send(%(#{meth}), *args, &blk) end @@ -58,6 +55,14 @@ module AbstractController end end + # Make a number of helper modules part of this class' default + # helpers. + # + # ==== Parameters + # *args<Array[Module]>:: Modules to be included + # block<Block>:: Evalulate the block in the context + # of the helper module. Any methods defined in the block + # will be helpers. def helper(*args, &block) args.flatten.each do |arg| case arg @@ -65,7 +70,18 @@ module AbstractController add_template_helper(arg) end end - master_helper_module.module_eval(&block) if block_given? + _helpers.module_eval(&block) if block_given? + end + + private + # Makes all the (instance) methods in the helper module available to templates + # rendered through this controller. + # + # ==== Parameters + # mod<Module>:: The module to include into the current helper module + # for the class + def add_template_helper(mod) + _helpers.module_eval { include mod } end end end diff --git a/actionpack/lib/action_controller/abstract/renderer.rb b/actionpack/lib/action_controller/abstract/renderer.rb index 28bdda4a75..611d3a16ce 100644 --- a/actionpack/lib/action_controller/abstract/renderer.rb +++ b/actionpack/lib/action_controller/abstract/renderer.rb @@ -29,6 +29,9 @@ module AbstractController # partial<Boolean>:: Whether or not the template to render is a partial # _partial:: If a partial, rather than a template, was rendered, return # the partial. + # helpers:: A module containing the helpers to be used in the view. This + # module should respond_to include. + # controller:: The controller that initialized the ActionView # # Override this method in a to change the default behavior. def _action_view diff --git a/actionpack/lib/action_controller/new_base/helpers.rb b/actionpack/lib/action_controller/new_base/helpers.rb index e8000be87b..8925dd3969 100644 --- a/actionpack/lib/action_controller/new_base/helpers.rb +++ b/actionpack/lib/action_controller/new_base/helpers.rb @@ -83,7 +83,7 @@ module ActionController end # Evaluate block in template class if given. - master_helper_module.module_eval(&block) if block_given? + _helpers.module_eval(&block) if block_given? end # Declares helper accessors for controller attributes. For example, the @@ -99,7 +99,7 @@ module ActionController def helpers unless @helper_proxy @helper_proxy = ActionView::Base.new - @helper_proxy.extend master_helper_module + @helper_proxy.extend _helpers else @helper_proxy end diff --git a/actionpack/test/controller/helper_test.rb b/actionpack/test/controller/helper_test.rb index 342cbfbcd3..515c4c9f52 100644 --- a/actionpack/test/controller/helper_test.rb +++ b/actionpack/test/controller/helper_test.rb @@ -127,7 +127,11 @@ class HelperTest < Test::Unit::TestCase end def test_all_helpers - methods = AllHelpersController.master_helper_module.instance_methods.map {|m| m.to_s} + methods = if defined?(ActionController::Http) + AllHelpersController._helpers.instance_methods.map {|m| m.to_s} + else + AllHelpersController.master_helper_module.instance_methods.map {|m| m.to_s} + end # abc_helper.rb assert methods.include?('bare_a') @@ -143,7 +147,12 @@ class HelperTest < Test::Unit::TestCase @controller_class.helpers_dir = File.dirname(__FILE__) + '/../fixtures/alternate_helpers' # Reload helpers - @controller_class.master_helper_module = Module.new + if defined?(ActionController::Http) + @controller_class._helpers = Module.new + else + @controller_class.master_helper_module = Module.new + end + @controller_class.helper :all # helpers/abc_helper.rb should not be included @@ -175,7 +184,11 @@ class HelperTest < Test::Unit::TestCase end def master_helper_methods - @controller_class.master_helper_module.instance_methods.map {|m| m.to_s } + if defined?(ActionController::Http) + @controller_class._helpers.instance_methods.map {|m| m.to_s } + else + @controller_class.master_helper_module.instance_methods.map {|m| m.to_s } + end end def missing_methods |