1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
module ActionController
# The Rails framework provides a large number of helpers for working with +assets+, +dates+, +forms+,
# +numbers+ and model objects, to name a few. These helpers are available to all templates
# by default.
#
# In addition to using the standard template helpers provided in the Rails framework, creating custom helpers to
# extract complicated logic or reusable functionality is strongly encouraged. By default, the controller will
# include a helper whose name matches that of the controller, e.g., <tt>MyController</tt> will automatically
# include <tt>MyHelper</tt>.
#
# Additional helpers can be specified using the +helper+ class method in <tt>ActionController::Base</tt> or any
# controller which inherits from it.
#
# ==== Examples
# The +to_s+ method from the Time class can be wrapped in a helper method to display a custom message if
# the Time object is blank:
#
# module FormattedTimeHelper
# def format_time(time, format=:long, blank_message=" ")
# time.blank? ? blank_message : time.to_s(format)
# end
# end
#
# FormattedTimeHelper can now be included in a controller, using the +helper+ class method:
#
# class EventsController < ActionController::Base
# helper FormattedTimeHelper
# def index
# @events = Event.find(:all)
# end
# end
#
# Then, in any view rendered by <tt>EventController</tt>, the <tt>format_time</tt> method can be called:
#
# <% @events.each do |event| -%>
# <p>
# <% format_time(event.time, :short, "N/A") %> | <%= event.name %>
# </p>
# <% end -%>
#
# Finally, assuming we have two event instances, one which has a time and one which does not,
# the output might look like this:
#
# 23 Aug 11:30 | Carolina Railhawks Soccer Match
# N/A | Carolina Railhaws Training Workshop
#
module Helpers
extend ActiveSupport::Concern
include AbstractController::Helpers
included do
extlib_inheritable_accessor(:helpers_path) do
defined?(Rails::Application) ? Rails::Application.paths.app.helpers.to_a : []
end
end
module ClassMethods
def helpers_dir
ActiveSupport::Deprecation.warn "ActionController::Base.helpers_dir is deprecated. " <<
"Please use ActionController::Base.helpers_path (which returns an array)"
self.helpers_path
end
def helpers_dir=(value)
ActiveSupport::Deprecation.warn "ActionController::Base.helpers_dir= is deprecated. " <<
"Please use ActionController::Base.helpers_path= (which is an array)"
self.helpers_path = Array(value)
end
def inherited(klass)
klass.class_eval { default_helper_module! unless name.blank? }
super
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
#
# ==== Parameters
# *attrs<Array[String, Symbol]>:: Names of attributes to be converted
# into helpers.
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
@helper_proxy ||= ActionView::Base.new.extend(_helpers)
end
private
# Overwrite _modules_for_helpers to accept :all as argument, which loads
# all helpers in helpers_dir.
#
# ==== Parameters
# args<Array[String, Symbol, Module, all]>:: A list of helpers
#
# ==== Returns
# Array[Module]:: A normalized list of modules for the list of
# helpers provided.
def _modules_for_helpers(args)
args += all_application_helpers if args.delete(:all)
super(args)
end
def default_helper_module!
module_name = name.sub(/Controller$/, '')
module_path = module_name.underscore
helper module_path
rescue MissingSourceFile => e
raise e unless e.is_missing? "helpers/#{module_path}_helper"
rescue NameError => e
raise e unless e.missing_name? "#{module_name}Helper"
end
# Extract helper names from files in app/helpers/**/*_helper.rb
def all_application_helpers
helpers = []
helpers_path.each do |path|
extract = /^#{Regexp.quote(path)}\/?(.*)_helper.rb$/
helpers += Dir["#{path}/**/*_helper.rb"].map { |file| file.sub(extract, '\1') }
end
helpers.sort!
helpers.uniq!
helpers
end
end
end
end
|