Add all the existing helpers related features to the new base
This commit is contained in:
parent
1d168afcb1
commit
e976c489e6
@ -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
|
||||
|
||||
|
@ -24,11 +24,30 @@ def inherited(klass)
|
||||
|
||||
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 @@ def #{meth}(*args, &blk)
|
||||
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
|
||||
|
||||
|
@ -3,23 +3,19 @@
|
||||
# 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")
|
||||
class_inheritable_accessor :helpers_dir
|
||||
self.helpers_dir = (defined?(RAILS_ROOT) ? "#{RAILS_ROOT}/app/helpers" : "app/helpers")
|
||||
|
||||
# Extend base with class methods to declare helpers.
|
||||
base.extend(ClassMethods)
|
||||
|
||||
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
|
||||
|
||||
|
@ -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'
|
||||
|
@ -4,9 +4,9 @@ class Base < Http
|
||||
|
||||
include AbstractController::Benchmarker
|
||||
include AbstractController::Callbacks
|
||||
include AbstractController::Helpers
|
||||
include AbstractController::Logger
|
||||
|
||||
|
||||
include ActionController::Helpers
|
||||
include ActionController::HideActions
|
||||
include ActionController::UrlFor
|
||||
include ActionController::Redirector
|
||||
|
133
actionpack/lib/action_controller/new_base/helpers.rb
Normal file
133
actionpack/lib/action_controller/new_base/helpers.rb
Normal file
@ -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
|
@ -27,7 +27,7 @@ def rescue_action(e) raise end
|
||||
end
|
||||
end
|
||||
|
||||
class ApplicationController < ActionController::Base
|
||||
class AllHelpersController < ActionController::Base
|
||||
helper :all
|
||||
end
|
||||
|
||||
@ -127,7 +127,7 @@ def test_helper_for_acronym_controller
|
||||
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 @@ def test_all_helpers_with_alternate_helper_dir
|
||||
end
|
||||
|
||||
def test_helper_proxy
|
||||
methods = ApplicationController.helpers.methods.map(&:to_s)
|
||||
methods = AllHelpersController.helpers.methods.map(&:to_s)
|
||||
|
||||
# ActionView
|
||||
assert methods.include?('pluralize')
|
||||
|
@ -2,6 +2,9 @@
|
||||
$:.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"
|
||||
|
||||
|
@ -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]
|
||||
|
Loading…
Reference in New Issue
Block a user