17 |
17 |
|
18 |
18 |
module Redmine #:nodoc:
|
19 |
19 |
|
20 |
|
class PluginNotFound < StandardError; end
|
|
20 |
class PluginNotFound < StandardError
|
|
21 |
attr_reader :plugin_id
|
|
22 |
def initialize(plug_id=nil)
|
|
23 |
super
|
|
24 |
@plugin_id = plug_id
|
|
25 |
end
|
|
26 |
end
|
21 |
27 |
class PluginRequirementError < StandardError; end
|
22 |
28 |
|
23 |
29 |
# Base class for Redmine plugins.
|
... | ... | |
44 |
50 |
# When rendered, the plugin settings value is available as the local variable +settings+
|
45 |
51 |
class Plugin
|
46 |
52 |
@registered_plugins = {}
|
|
53 |
@deferred_plugins = {}
|
|
54 |
|
47 |
55 |
class << self
|
48 |
|
attr_reader :registered_plugins
|
|
56 |
attr_reader :registered_plugins, :deferred_plugins
|
49 |
57 |
private :new
|
50 |
58 |
|
51 |
59 |
def def_field(*names)
|
... | ... | |
63 |
71 |
|
64 |
72 |
# Plugin constructor
|
65 |
73 |
def self.register(id, &block)
|
66 |
|
p = new(id)
|
67 |
|
p.instance_eval(&block)
|
68 |
|
# Set a default name if it was not provided during registration
|
69 |
|
p.name(id.to_s.humanize) if p.name.nil?
|
70 |
|
# Adds plugin locales if any
|
71 |
|
# YAML translation files should be found under <plugin>/config/locales/
|
72 |
|
::I18n.load_path += Dir.glob(File.join(RAILS_ROOT, 'vendor', 'plugins', id.to_s, 'config', 'locales', '*.yml'))
|
73 |
|
registered_plugins[id] = p
|
|
74 |
begin
|
|
75 |
id = id.to_sym
|
|
76 |
p = new(id)
|
|
77 |
p.instance_eval(&block)
|
|
78 |
# Set a default name if it was not provided during registration
|
|
79 |
p.name(id.to_s.humanize) if p.name.nil?
|
|
80 |
# Adds plugin locales if any
|
|
81 |
# YAML translation files should be found under <plugin>/config/locales/
|
|
82 |
::I18n.load_path += Dir.glob(File.join(RAILS_ROOT, 'vendor', 'plugins', id.to_s, 'config', 'locales', '*.yml'))
|
|
83 |
registered_plugins[id] = p
|
|
84 |
|
|
85 |
# If there are plugins waiting for us to be loaded, we try loading those, again
|
|
86 |
if deferred_plugins[id]
|
|
87 |
deferred_plugins[id].each do |ary|
|
|
88 |
plugin_id, block = ary
|
|
89 |
register(plugin_id, &block)
|
|
90 |
end
|
|
91 |
deferred_plugins.delete(id)
|
|
92 |
end
|
|
93 |
|
|
94 |
return p
|
|
95 |
rescue PluginNotFound => e
|
|
96 |
if RedminePluginLocator.instance.plugin_names.include? e.plugin_id.to_s
|
|
97 |
# The required plugin is going to be loaded later, defer loading this plugin
|
|
98 |
(deferred_plugins[e.plugin_id] ||= []) << [id, block]
|
|
99 |
return p
|
|
100 |
else
|
|
101 |
raise e
|
|
102 |
end
|
|
103 |
end
|
74 |
104 |
end
|
75 |
105 |
|
76 |
106 |
# Returns an array off all registered plugins
|
... | ... | |
81 |
112 |
# Finds a plugin by its id
|
82 |
113 |
# Returns a PluginNotFound exception if the plugin doesn't exist
|
83 |
114 |
def self.find(id)
|
84 |
|
registered_plugins[id.to_sym] || raise(PluginNotFound)
|
|
115 |
registered_plugins[id.to_sym] || raise(PluginNotFound.new(id.to_sym))
|
85 |
116 |
end
|
86 |
117 |
|
87 |
118 |
# Clears the registered plugins hash
|