Skip to content

HTTPS clone URL

Subversion checkout URL

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