提交 e976c489 编写于 作者: P Pratik Naik

Add all the existing helpers related features to the new base

上级 1d168afc
......@@ -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")
# 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
......
......@@ -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
......
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"
......
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]
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册