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