##// END OF EJS Templates
Required file lib/redmine/hook.rb is patching autoloaded ApplicationHelper (#20508)....
Jean-Philippe Lang -
r14128:5626ee94ed8a
parent child
Show More
@@ -1,175 +1,175
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2015 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 module Redmine
19 19 module Hook
20 20 @@listener_classes = []
21 21 @@listeners = nil
22 22 @@hook_listeners = {}
23 23
24 24 class << self
25 25 # Adds a listener class.
26 26 # Automatically called when a class inherits from Redmine::Hook::Listener.
27 27 def add_listener(klass)
28 28 raise "Hooks must include Singleton module." unless klass.included_modules.include?(Singleton)
29 29 @@listener_classes << klass
30 30 clear_listeners_instances
31 31 end
32 32
33 33 # Returns all the listener instances.
34 34 def listeners
35 35 @@listeners ||= @@listener_classes.collect {|listener| listener.instance}
36 36 end
37 37
38 38 # Returns the listener instances for the given hook.
39 39 def hook_listeners(hook)
40 40 @@hook_listeners[hook] ||= listeners.select {|listener| listener.respond_to?(hook)}
41 41 end
42 42
43 43 # Clears all the listeners.
44 44 def clear_listeners
45 45 @@listener_classes = []
46 46 clear_listeners_instances
47 47 end
48 48
49 49 # Clears all the listeners instances.
50 50 def clear_listeners_instances
51 51 @@listeners = nil
52 52 @@hook_listeners = {}
53 53 end
54 54
55 55 # Calls a hook.
56 56 # Returns the listeners response.
57 57 def call_hook(hook, context={})
58 58 [].tap do |response|
59 59 hls = hook_listeners(hook)
60 60 if hls.any?
61 61 hls.each {|listener| response << listener.send(hook, context)}
62 62 end
63 63 end
64 64 end
65 65 end
66 66
67 67 # Base class for hook listeners.
68 68 class Listener
69 69 include Singleton
70 70 include Redmine::I18n
71 71
72 72 # Registers the listener
73 73 def self.inherited(child)
74 74 Redmine::Hook.add_listener(child)
75 75 super
76 76 end
77 77
78 78 end
79 79
80 80 # Listener class used for views hooks.
81 81 # Listeners that inherit this class will include various helpers by default.
82 82 class ViewListener < Listener
83 83 include ERB::Util
84 84 include ActionView::Helpers::TagHelper
85 85 include ActionView::Helpers::FormHelper
86 86 include ActionView::Helpers::FormTagHelper
87 87 include ActionView::Helpers::FormOptionsHelper
88 88 include ActionView::Helpers::JavaScriptHelper
89 89 include ActionView::Helpers::NumberHelper
90 90 include ActionView::Helpers::UrlHelper
91 91 include ActionView::Helpers::AssetTagHelper
92 92 include ActionView::Helpers::TextHelper
93 93 include Rails.application.routes.url_helpers
94 94 include ApplicationHelper
95 95
96 96 # Default to creating links using only the path. Subclasses can
97 97 # change this default as needed
98 98 def self.default_url_options
99 99 {:only_path => true, :script_name => Redmine::Utils.relative_url_root}
100 100 end
101 101
102 102 # Helper method to directly render using the context,
103 103 # render_options must be valid #render options.
104 104 #
105 105 # class MyHook < Redmine::Hook::ViewListener
106 106 # render_on :view_issues_show_details_bottom, :partial => "show_more_data"
107 107 # end
108 108 #
109 109 # class MultipleHook < Redmine::Hook::ViewListener
110 110 # render_on :view_issues_show_details_bottom,
111 111 # {:partial => "show_more_data"},
112 112 # {:partial => "show_even_more_data"}
113 113 # end
114 114 #
115 115 def self.render_on(hook, *render_options)
116 116 define_method hook do |context|
117 117 render_options.map do |options|
118 118 if context[:hook_caller].respond_to?(:render)
119 119 context[:hook_caller].send(:render, {:locals => context}.merge(options))
120 120 elsif context[:controller].is_a?(ActionController::Base)
121 121 context[:controller].send(:render_to_string, {:locals => context}.merge(options))
122 122 else
123 123 raise "Cannot render #{self.name} hook from #{context[:hook_caller].class.name}"
124 124 end
125 125 end
126 126 end
127 127 end
128
128
129 129 def controller
130 130 nil
131 131 end
132
132
133 133 def config
134 134 ActionController::Base.config
135 135 end
136 136 end
137 137
138 138 # Helper module included in ApplicationHelper and ActionController so that
139 139 # hooks can be called in views like this:
140 140 #
141 141 # <%= call_hook(:some_hook) %>
142 142 # <%= call_hook(:another_hook, :foo => 'bar') %>
143 143 #
144 144 # Or in controllers like:
145 145 # call_hook(:some_hook)
146 146 # call_hook(:another_hook, :foo => 'bar')
147 147 #
148 148 # Hooks added to views will be concatenated into a string. Hooks added to
149 149 # controllers will return an array of results.
150 150 #
151 151 # Several objects are automatically added to the call context:
152 152 #
153 153 # * project => current project
154 154 # * request => Request instance
155 155 # * controller => current Controller instance
156 156 # * hook_caller => object that called the hook
157 157 #
158 158 module Helper
159 159 def call_hook(hook, context={})
160 160 if is_a?(ActionController::Base)
161 161 default_context = {:controller => self, :project => @project, :request => request, :hook_caller => self}
162 162 Redmine::Hook.call_hook(hook, default_context.merge(context))
163 163 else
164 164 default_context = { :project => @project, :hook_caller => self }
165 165 default_context[:controller] = controller if respond_to?(:controller)
166 166 default_context[:request] = request if respond_to?(:request)
167 167 Redmine::Hook.call_hook(hook, default_context.merge(context)).join(' ').html_safe
168 168 end
169 169 end
170 170 end
171 171 end
172 172 end
173 173
174 ApplicationHelper.send(:include, Redmine::Hook::Helper)
174 ActionView::Base.send(:include, Redmine::Hook::Helper)
175 175 ActionController::Base.send(:include, Redmine::Hook::Helper)
General Comments 0
You need to be logged in to leave comments. Login now