aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack
diff options
context:
space:
mode:
authorPratik Naik <pratiknaik@gmail.com>2009-05-23 00:17:05 +0200
committerPratik Naik <pratiknaik@gmail.com>2009-05-23 00:17:10 +0200
commite976c489e6416cdc4714721df78dd43dd6d13d99 (patch)
treec5e5c96ef0bd5cd522ddc492a527e53685a0d58b /actionpack
parent1d168afcb146872cb7e49b6d513629fbb19e39b0 (diff)
downloadrails-e976c489e6416cdc4714721df78dd43dd6d13d99.tar.gz
rails-e976c489e6416cdc4714721df78dd43dd6d13d99.tar.bz2
rails-e976c489e6416cdc4714721df78dd43dd6d13d99.zip
Add all the existing helpers related features to the new base
Diffstat (limited to 'actionpack')
-rw-r--r--actionpack/Rakefile2
-rw-r--r--actionpack/lib/action_controller/abstract/helpers.rb27
-rw-r--r--actionpack/lib/action_controller/base/helpers.rb22
-rw-r--r--actionpack/lib/action_controller/new_base.rb1
-rw-r--r--actionpack/lib/action_controller/new_base/base.rb4
-rw-r--r--actionpack/lib/action_controller/new_base/helpers.rb133
-rw-r--r--actionpack/test/controller/helper_test.rb6
-rw-r--r--actionpack/test/new_base/abstract_unit.rb3
-rw-r--r--actionpack/test/new_base/render_text_test.rb3
9 files changed, 175 insertions, 26 deletions
diff --git a/actionpack/Rakefile b/actionpack/Rakefile
index c9ed9ac532..0ce6f7823b 100644
--- a/actionpack/Rakefile
+++ b/actionpack/Rakefile
@@ -66,7 +66,7 @@ Rake::TestTask.new(:test_new_base_on_old_tests) do |t|
render render_json render_xml
send_file request_forgery_protection rescue url_rewriter verification webservice
http_basic_authentication http_digest_authentication
- action_pack_assertions assert_select filter_params
+ action_pack_assertions assert_select filter_params helper
).map { |name| "test/controller/#{name}_test.rb" }
end
diff --git a/actionpack/lib/action_controller/abstract/helpers.rb b/actionpack/lib/action_controller/abstract/helpers.rb
index 968d3080c1..41decfd0c7 100644
--- a/actionpack/lib/action_controller/abstract/helpers.rb
+++ b/actionpack/lib/action_controller/abstract/helpers.rb
@@ -24,11 +24,30 @@ module AbstractController
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
+ # helper_method :current_user, :logged_in?
+ #
+ # def current_user
+ # @current_user ||= User.find_by_id(session[:user])
+ # end
+ #
+ # def logged_in?
+ # current_user != nil
+ # end
+ # end
+ #
+ # In a view:
+ # <% if logged_in? -%>Welcome, <%= current_user.name %><% end -%>
def helper_method(*meths)
meths.flatten.each do |meth|
master_helper_module.class_eval <<-ruby_eval, __FILE__, __LINE__ + 1
@@ -39,14 +58,14 @@ module AbstractController
end
end
- def helper(*args, &blk)
+ def helper(*args, &block)
args.flatten.each do |arg|
case arg
when Module
add_template_helper(arg)
end
end
- master_helper_module.module_eval(&blk) if block_given?
+ master_helper_module.module_eval(&block) if block_given?
end
end
diff --git a/actionpack/lib/action_controller/base/helpers.rb b/actionpack/lib/action_controller/base/helpers.rb
index ba65032f6a..96fa7896a9 100644
--- a/actionpack/lib/action_controller/base/helpers.rb
+++ b/actionpack/lib/action_controller/base/helpers.rb
@@ -3,23 +3,19 @@ require 'active_support/dependencies'
# FIXME: helper { ... } is broken on Ruby 1.9
module ActionController #:nodoc:
module Helpers #:nodoc:
- def self.included(base)
+ extend ActiveSupport::DependencyModule
+
+ included do
# Initialize the base module to aggregate its helpers.
- base.class_inheritable_accessor :master_helper_module
- base.master_helper_module = Module.new
+ class_inheritable_accessor :master_helper_module
+ self.master_helper_module = Module.new
# Set the default directory for helpers
- base.class_inheritable_accessor :helpers_dir
- base.helpers_dir = (defined?(RAILS_ROOT) ? "#{RAILS_ROOT}/app/helpers" : "app/helpers")
-
- # Extend base with class methods to declare helpers.
- base.extend(ClassMethods)
+ class_inheritable_accessor :helpers_dir
+ self.helpers_dir = (defined?(RAILS_ROOT) ? "#{RAILS_ROOT}/app/helpers" : "app/helpers")
- base.class_eval do
- # Wrap inherited to create a new master helper module for subclasses.
- class << self
- alias_method_chain :inherited, :helper
- end
+ class << self
+ alias_method_chain :inherited, :helper
end
end
diff --git a/actionpack/lib/action_controller/new_base.rb b/actionpack/lib/action_controller/new_base.rb
index 41b2a859bc..d6107d3653 100644
--- a/actionpack/lib/action_controller/new_base.rb
+++ b/actionpack/lib/action_controller/new_base.rb
@@ -13,6 +13,7 @@ module ActionController
autoload :Testing, "action_controller/new_base/testing"
autoload :UrlFor, "action_controller/new_base/url_for"
autoload :Session, "action_controller/new_base/session"
+ autoload :Helpers, "action_controller/new_base/helpers"
# Ported modules
# require 'action_controller/routing'
diff --git a/actionpack/lib/action_controller/new_base/base.rb b/actionpack/lib/action_controller/new_base/base.rb
index 0c85896a00..6340b7fde9 100644
--- a/actionpack/lib/action_controller/new_base/base.rb
+++ b/actionpack/lib/action_controller/new_base/base.rb
@@ -4,9 +4,9 @@ module ActionController
include AbstractController::Benchmarker
include AbstractController::Callbacks
- include AbstractController::Helpers
include AbstractController::Logger
-
+
+ include ActionController::Helpers
include ActionController::HideActions
include ActionController::UrlFor
include ActionController::Redirector
diff --git a/actionpack/lib/action_controller/new_base/helpers.rb b/actionpack/lib/action_controller/new_base/helpers.rb
new file mode 100644
index 0000000000..401741c249
--- /dev/null
+++ b/actionpack/lib/action_controller/new_base/helpers.rb
@@ -0,0 +1,133 @@
+require 'active_support/core_ext/load_error'
+require 'active_support/core_ext/name_error'
+require 'active_support/dependencies'
+
+module ActionController
+ module Helpers
+ extend ActiveSupport::DependencyModule
+
+ depends_on AbstractController::Helpers
+
+ included do
+ # Set the default directory for helpers
+ class_inheritable_accessor :helpers_dir
+ self.helpers_dir = (defined?(RAILS_ROOT) ? "#{RAILS_ROOT}/app/helpers" : "app/helpers")
+ end
+
+ module ClassMethods
+ def inherited(klass)
+ # klass.master_helper_module = Module.new
+ # klass.master_helper_module.__send__ :include, master_helper_module
+ klass.__send__ :default_helper_module!
+ super
+ end
+
+ # The +helper+ class method can take a series of helper module names, a block, or both.
+ #
+ # * <tt>*args</tt>: One or more modules, strings or symbols, or the special symbol <tt>:all</tt>.
+ # * <tt>&block</tt>: A block defining helper methods.
+ #
+ # ==== Examples
+ # When the argument is a string or symbol, the method will provide the "_helper" suffix, require the file
+ # and include the module in the template class. The second form illustrates how to include custom helpers
+ # when working with namespaced controllers, or other cases where the file containing the helper definition is not
+ # in one of Rails' standard load paths:
+ # helper :foo # => requires 'foo_helper' and includes FooHelper
+ # helper 'resources/foo' # => requires 'resources/foo_helper' and includes Resources::FooHelper
+ #
+ # When the argument is a module it will be included directly in the template class.
+ # helper FooHelper # => includes FooHelper
+ #
+ # When the argument is the symbol <tt>:all</tt>, the controller will include all helpers beneath
+ # <tt>ActionController::Base.helpers_dir</tt> (defaults to <tt>app/helpers/**/*.rb</tt> under RAILS_ROOT).
+ # helper :all
+ #
+ # Additionally, the +helper+ class method can receive and evaluate a block, making the methods defined available
+ # to the template.
+ # # One line
+ # helper { def hello() "Hello, world!" end }
+ # # Multi-line
+ # helper do
+ # def foo(bar)
+ # "#{bar} is the very best"
+ # end
+ # end
+ #
+ # Finally, all the above styles can be mixed together, and the +helper+ method can be invoked with a mix of
+ # +symbols+, +strings+, +modules+ and blocks.
+ # helper(:three, BlindHelper) { def mice() 'mice' end }
+ #
+ def helper(*args, &block)
+ args.flatten.each do |arg|
+ case arg
+ when :all
+ helper all_application_helpers
+ when String, Symbol
+ file_name = arg.to_s.underscore + '_helper'
+ class_name = file_name.camelize
+
+ begin
+ require_dependency(file_name)
+ rescue LoadError => load_error
+ requiree = / -- (.*?)(\.rb)?$/.match(load_error.message).to_a[1]
+ if requiree == file_name
+ msg = "Missing helper file helpers/#{file_name}.rb"
+ raise LoadError.new(msg).copy_blame!(load_error)
+ else
+ raise
+ end
+ end
+
+ add_template_helper(class_name.constantize)
+ else
+ # Explcit 'return' here so that the supplied block ( if any ) doesn't get included twice
+ return super
+ end
+ end
+
+ # Evaluate block in template class if given.
+ master_helper_module.module_eval(&block) if block_given?
+ end
+
+ # Declares helper accessors for controller attributes. For example, the
+ # following adds new +name+ and <tt>name=</tt> instance methods to a
+ # controller and makes them available to the view:
+ # helper_attr :name
+ # attr_accessor :name
+ def helper_attr(*attrs)
+ attrs.flatten.each { |attr| helper_method(attr, "#{attr}=") }
+ end
+
+ # Provides a proxy to access helpers methods from outside the view.
+ def helpers
+ unless @helper_proxy
+ @helper_proxy = ActionView::Base.new
+ @helper_proxy.extend master_helper_module
+ else
+ @helper_proxy
+ end
+ end
+
+ private
+
+ def default_helper_module!
+ unless name.blank?
+ module_name = name.sub(/Controller$|$/, 'Helper')
+ module_path = module_name.split('::').map { |m| m.underscore }.join('/')
+ require_dependency module_path
+ helper module_name.constantize
+ end
+ rescue MissingSourceFile => e
+ raise unless e.is_missing? module_path
+ rescue NameError => e
+ raise unless e.missing_name? module_name
+ end
+
+ # Extract helper names from files in app/helpers/**/*.rb
+ def all_application_helpers
+ extract = /^#{Regexp.quote(helpers_dir)}\/?(.*)_helper.rb$/
+ Dir["#{helpers_dir}/**/*_helper.rb"].map { |file| file.sub extract, '\1' }
+ end
+ end # ClassMethods
+ end
+end
diff --git a/actionpack/test/controller/helper_test.rb b/actionpack/test/controller/helper_test.rb
index 3bbda9eb3a..5b9feb3630 100644
--- a/actionpack/test/controller/helper_test.rb
+++ b/actionpack/test/controller/helper_test.rb
@@ -27,7 +27,7 @@ module Fun
end
end
-class ApplicationController < ActionController::Base
+class AllHelpersController < ActionController::Base
helper :all
end
@@ -127,7 +127,7 @@ class HelperTest < Test::Unit::TestCase
end
def test_all_helpers
- methods = ApplicationController.master_helper_module.instance_methods.map(&:to_s)
+ methods = AllHelpersController.master_helper_module.instance_methods.map(&:to_s)
# abc_helper.rb
assert methods.include?('bare_a')
@@ -154,7 +154,7 @@ class HelperTest < Test::Unit::TestCase
end
def test_helper_proxy
- methods = ApplicationController.helpers.methods.map(&:to_s)
+ methods = AllHelpersController.helpers.methods.map(&:to_s)
# ActionView
assert methods.include?('pluralize')
diff --git a/actionpack/test/new_base/abstract_unit.rb b/actionpack/test/new_base/abstract_unit.rb
index 5df3467ff5..569e4e764f 100644
--- a/actionpack/test/new_base/abstract_unit.rb
+++ b/actionpack/test/new_base/abstract_unit.rb
@@ -2,6 +2,9 @@ $:.unshift(File.dirname(__FILE__) + '/../../lib')
$:.unshift(File.dirname(__FILE__) + '/../../../activesupport/lib')
$:.unshift(File.dirname(__FILE__) + '/../lib')
+$:.unshift(File.dirname(__FILE__) + '/../fixtures/helpers')
+$:.unshift(File.dirname(__FILE__) + '/../fixtures/alternate_helpers')
+
ENV['new_base'] = "true"
$stderr.puts "Running old tests on new_base"
diff --git a/actionpack/test/new_base/render_text_test.rb b/actionpack/test/new_base/render_text_test.rb
index aed903ee8a..ffc149283b 100644
--- a/actionpack/test/new_base/render_text_test.rb
+++ b/actionpack/test/new_base/render_text_test.rb
@@ -1,8 +1,5 @@
require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
-class ApplicationController < ActionController::Base
-end
-
module RenderText
class SimpleController < ActionController::Base
self.view_paths = [ActionView::Template::FixturePath.new]