Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 165 lines (152 sloc) 5.776 kB
684c2dc @josevalim Remove ActionMailer helpers and rely on AbstractController one.
josevalim authored
1 require 'active_support/dependencies'
e5ab4b0 @jeremy Convert to class_attribute
jeremy authored
2 require 'active_support/core_ext/class/attribute'
3 require 'active_support/core_ext/module/delegation'
7cff54f @fxn name.blank? -> anonymous?
fxn authored
4 require 'active_support/core_ext/module/anonymous'
684c2dc @josevalim Remove ActionMailer helpers and rely on AbstractController one.
josevalim authored
5
6001cea @wycats Helpers with an initial test
wycats authored
6 module AbstractController
7 module Helpers
4e50a35 @josh Break up DependencyModule's dual function of providing a "depend_on" …
josh authored
8 extend ActiveSupport::Concern
2854535 @josh Make module dependency DSL opt in
josh authored
9
83f4d86 @dhh Rename the RenderingController module to just plain Rendering
dhh authored
10 include Rendering
af40fa6 @josh Prefer "included" language over "setup"
josh authored
11
e58b276 @wycats Experimental: Improve performance of ActionView by preventing method …
wycats authored
12 def self.next_serial
13 @helper_serial ||= 0
14 @helper_serial += 1
15 end
16
af40fa6 @josh Prefer "included" language over "setup"
josh authored
17 included do
e5ab4b0 @jeremy Convert to class_attribute
jeremy authored
18 class_attribute :_helpers, :_helper_serial
19 delegate :_helpers, :to => :'self.class'
20 self._helpers = Module.new
21 self._helper_serial = ::AbstractController::Helpers.next_serial
6001cea @wycats Helpers with an initial test
wycats authored
22 end
030dfe3 @wycats More community code review :)
wycats authored
23
6001cea @wycats Helpers with an initial test
wycats authored
24 module ClassMethods
acb2447 Write documentation for AbstractController::Helpers
Yehuda Katz + Carl Lerche authored
25 # When a class is inherited, wrap its helper module in a new module.
26 # This ensures that the parent class's module can be changed
27 # independently of the child class's.
6001cea @wycats Helpers with an initial test
wycats authored
28 def inherited(klass)
acb2447 Write documentation for AbstractController::Helpers
Yehuda Katz + Carl Lerche authored
29 helpers = _helpers
30 klass._helpers = Module.new { include helpers }
7cff54f @fxn name.blank? -> anonymous?
fxn authored
31 klass.class_eval { default_helper_module! unless anonymous? }
6001cea @wycats Helpers with an initial test
wycats authored
32 super
33 end
e976c48 @lifo Add all the existing helpers related features to the new base
lifo authored
34
35 # Declare a controller method as a helper. For example, the following
36 # makes the +current_user+ controller method available to the view:
37 # class ApplicationController < ActionController::Base
38 # helper_method :current_user, :logged_in?
39 #
40 # def current_user
41 # @current_user ||= User.find_by_id(session[:user])
42 # end
43 #
44 # def logged_in?
45 # current_user != nil
46 # end
47 # end
48 #
49 # In a view:
50 # <% if logged_in? -%>Welcome, <%= current_user.name %><% end -%>
acb2447 Write documentation for AbstractController::Helpers
Yehuda Katz + Carl Lerche authored
51 #
52 # ==== Parameters
53 # meths<Array[#to_s]>:: The name of a method on the controller
54 # to be made available on the view.
6001cea @wycats Helpers with an initial test
wycats authored
55 def helper_method(*meths)
56 meths.flatten.each do |meth|
acb2447 Write documentation for AbstractController::Helpers
Yehuda Katz + Carl Lerche authored
57 _helpers.class_eval <<-ruby_eval, __FILE__, __LINE__ + 1
6001cea @wycats Helpers with an initial test
wycats authored
58 def #{meth}(*args, &blk)
59 controller.send(%(#{meth}), *args, &blk)
60 end
61 ruby_eval
62 end
63 end
de20324 @josh Revert "Revert "Whitespace!""
josh authored
64
684c2dc @josevalim Remove ActionMailer helpers and rely on AbstractController one.
josevalim authored
65 # The +helper+ class method can take a series of helper module names, a block, or both.
acb2447 Write documentation for AbstractController::Helpers
Yehuda Katz + Carl Lerche authored
66 #
67 # ==== Parameters
684c2dc @josevalim Remove ActionMailer helpers and rely on AbstractController one.
josevalim authored
68 # *args<Array[Module, Symbol, String, :all]>
69 # block<Block>:: A block defining helper methods
70 #
71 # ==== Examples
72 # When the argument is a module it will be included directly in the template class.
73 # helper FooHelper # => includes FooHelper
74 #
75 # When the argument is a string or symbol, the method will provide the "_helper" suffix, require the file
76 # and include the module in the template class. The second form illustrates how to include custom helpers
77 # when working with namespaced controllers, or other cases where the file containing the helper definition is not
78 # in one of Rails' standard load paths:
79 # helper :foo # => requires 'foo_helper' and includes FooHelper
80 # helper 'resources/foo' # => requires 'resources/foo_helper' and includes Resources::FooHelper
81 #
82 # Additionally, the +helper+ class method can receive and evaluate a block, making the methods defined available
83 # to the template.
84 #
85 # # One line
86 # helper { def hello() "Hello, world!" end }
87 #
88 # # Multi-line
89 # helper do
90 # def foo(bar)
91 # "#{bar} is the very best"
92 # end
93 # end
94 #
95 # Finally, all the above styles can be mixed together, and the +helper+ method can be invoked with a mix of
96 # +symbols+, +strings+, +modules+ and blocks.
97 #
98 # helper(:three, BlindHelper) { def mice() 'mice' end }
99 #
e976c48 @lifo Add all the existing helpers related features to the new base
lifo authored
100 def helper(*args, &block)
e58b276 @wycats Experimental: Improve performance of ActionView by preventing method …
wycats authored
101 self._helper_serial = AbstractController::Helpers.next_serial + 1
102
ac956c4 Update AP to start locking down a public API. This work is parallel t…
Yehuda Katz authored
103 modules_for_helpers(args).each do |mod|
684c2dc @josevalim Remove ActionMailer helpers and rely on AbstractController one.
josevalim authored
104 add_template_helper(mod)
6001cea @wycats Helpers with an initial test
wycats authored
105 end
684c2dc @josevalim Remove ActionMailer helpers and rely on AbstractController one.
josevalim authored
106
acb2447 Write documentation for AbstractController::Helpers
Yehuda Katz + Carl Lerche authored
107 _helpers.module_eval(&block) if block_given?
108 end
109
110 private
111 # Makes all the (instance) methods in the helper module available to templates
112 # rendered through this controller.
113 #
114 # ==== Parameters
115 # mod<Module>:: The module to include into the current helper module
116 # for the class
117 def add_template_helper(mod)
118 _helpers.module_eval { include mod }
6001cea @wycats Helpers with an initial test
wycats authored
119 end
684c2dc @josevalim Remove ActionMailer helpers and rely on AbstractController one.
josevalim authored
120
121 # Returns a list of modules, normalized from the acceptable kinds of
122 # helpers with the following behavior:
123 #
124 # String or Symbol:: :FooBar or "FooBar" becomes "foo_bar_helper",
125 # and "foo_bar_helper.rb" is loaded using require_dependency.
126 #
127 # Module:: No further processing
128 #
129 # After loading the appropriate files, the corresponding modules
130 # are returned.
131 #
132 # ==== Parameters
133 # args<Array[String, Symbol, Module]>:: A list of helpers
134 #
135 # ==== Returns
136 # Array[Module]:: A normalized list of modules for the list of
137 # helpers provided.
ac956c4 Update AP to start locking down a public API. This work is parallel t…
Yehuda Katz authored
138 def modules_for_helpers(args)
684c2dc @josevalim Remove ActionMailer helpers and rely on AbstractController one.
josevalim authored
139 args.flatten.map! do |arg|
140 case arg
141 when String, Symbol
142 file_name = "#{arg.to_s.underscore}_helper"
143 require_dependency(file_name, "Missing helper file helpers/%s.rb")
144 file_name.camelize.constantize
145 when Module
146 arg
147 else
148 raise ArgumentError, "helper must be a String, Symbol, or Module"
149 end
150 end
151 end
0e063f4 @josevalim Fix some backward incompatible behavior on AM.
josevalim authored
152
153 def default_helper_module!
154 module_name = name.sub(/Controller$/, '')
155 module_path = module_name.underscore
156 helper module_path
157 rescue MissingSourceFile => e
158 raise e unless e.is_missing? "helpers/#{module_path}_helper"
159 rescue NameError => e
160 raise e unless e.missing_name? "#{module_name}Helper"
161 end
6001cea @wycats Helpers with an initial test
wycats authored
162 end
163 end
de20324 @josh Revert "Revert "Whitespace!""
josh authored
164 end
Something went wrong with that request. Please try again.