Class: DiscoursePluginRegistry
- Inherits:
-
Object
- Object
- DiscoursePluginRegistry
- Defined in:
- lib/discourse_plugin_registry.rb
Overview
A class that handles interaction between a plugin and the Discourse App.
Constant Summary collapse
- JS_REGEX =
/\.js$|\.js\.erb$|\.js\.es6\z/
- VENDORED_CORE_PRETTY_TEXT_MAP =
{ "moment.js" => "vendor/assets/javascripts/moment.js", "moment-timezone.js" => "vendor/assets/javascripts/moment-timezone-with-data.js", }
- @@register_names =
Set.new
Class Method Summary collapse
- .apply_modifier(name, arg, *more_args) ⇒ Object
- .build_html(name, ctx = nil) ⇒ Object
- .clear_modifiers! ⇒ Object
- .core_asset_for_name(name) ⇒ Object
-
.define_filtered_register(register_name) ⇒ Object
Plugins often need to add values to a list, and we need to filter those lists at runtime to ignore values from disabled plugins.
-
.define_register(register_name, type) ⇒ Object
Plugins often need to be able to register additional handlers, data, or classes that will be used by core classes.
- .register_asset(asset, opts = nil, plugin_directory_name = nil) ⇒ Object
- .register_auth_provider(auth_provider) ⇒ Object
- .register_html_builder(name, &block) ⇒ Object
- .register_locale(locale, options = {}) ⇒ Object
- .register_mail_poller(mail_poller) ⇒ Object
- .register_modifier(plugin_instance, name, &blk) ⇒ Object
- .register_seed_data(key, value) ⇒ Object
- .register_seed_path_builder(&block) ⇒ Object
- .register_seedfu_filter(filter = nil) ⇒ Object
- .register_service_worker(filename, options = {}) ⇒ Object
- .register_svg_icon(icon) ⇒ Object
- .reset! ⇒ Object
- .reset_register!(register_name) ⇒ Object
- .seed_paths ⇒ Object
- .stylesheets_exists?(plugin_directory_name, target = nil) ⇒ Boolean
- .unregister_modifier(plugin_instance, name, &blk) ⇒ Object
Instance Method Summary collapse
- #register_archetype(name, options = {}) ⇒ Object
- #register_css(filename, plugin_directory_name) ⇒ Object
- #register_js(filename, options = {}) ⇒ Object
Class Method Details
.apply_modifier(name, arg, *more_args) ⇒ Object
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 |
# File 'lib/discourse_plugin_registry.rb', line 268 def self.apply_modifier(name, arg, *more_args) return arg if !@modifiers registered_modifiers = @modifiers[name] return arg if !registered_modifiers # iterate as fast as possible to minimize cost (avoiding each) # also erases one stack frame length = registered_modifiers.length index = 0 while index < length plugin_instance, block = registered_modifiers[index] arg = block.call(arg, *more_args) if plugin_instance.enabled? index += 1 end arg end |
.build_html(name, ctx = nil) ⇒ Object
216 217 218 219 |
# File 'lib/discourse_plugin_registry.rb', line 216 def self.build_html(name, ctx = nil) builders = html_builders[name] || [] builders.map { |b| b.call(ctx) }.join("\n").html_safe end |
.clear_modifiers! ⇒ Object
243 244 245 246 247 248 |
# File 'lib/discourse_plugin_registry.rb', line 243 def self.clear_modifiers! if Rails.env.test? && GlobalSetting.load_plugins? raise "Clearing modifiers during a plugin spec run will affect all future specs. Use unregister_modifier instead." end @modifiers = nil end |
.core_asset_for_name(name) ⇒ Object
237 238 239 240 241 |
# File 'lib/discourse_plugin_registry.rb', line 237 def self.core_asset_for_name(name) asset = VENDORED_CORE_PRETTY_TEXT_MAP[name] raise KeyError, "Asset #{name} not found in #{VENDORED_CORE_PRETTY_TEXT_MAP}" unless asset asset end |
.define_filtered_register(register_name) ⇒ Object
Plugins often need to add values to a list, and we need to filter those lists at runtime to ignore values from disabled plugins. Unlike define_register, the type of the register cannot be defined, and is always Array.
Create a new register (see ‘define_register`) with some additions:
- Register is created in a class variable using the specified name/type
- Defines singleton method to access the register
- Defines instance method as a shortcut to the singleton method
- Automatically deletes the register on registry.reset!
40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/discourse_plugin_registry.rb', line 40 def self.define_filtered_register(register_name) return if respond_to?(register_name) define_register(register_name, Array) singleton_class.alias_method :"_raw_#{register_name}", :"#{register_name}" define_singleton_method(register_name) do public_send(:"_raw_#{register_name}").filter_map { |h| h[:value] if h[:plugin].enabled? }.uniq end define_singleton_method("register_#{register_name.to_s.singularize}") do |value, plugin| public_send(:"_raw_#{register_name}") << { plugin: plugin, value: value } end end |
.define_register(register_name, type) ⇒ Object
Plugins often need to be able to register additional handlers, data, or classes that will be used by core classes. This should be used if you need to control which type the registry is, and if it doesn’t need to be removed if the plugin is disabled.
Shortcut to create new register in the plugin registry
- Register is created in a class variable using the specified name/type
- Defines singleton method to access the register
- Defines instance method as a shortcut to the singleton method
- Automatically deletes the register on registry.reset!
19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/discourse_plugin_registry.rb', line 19 def self.define_register(register_name, type) return if respond_to?(register_name) @@register_names << register_name define_singleton_method(register_name) do instance_variable_get(:"@#{register_name}") || instance_variable_set(:"@#{register_name}", type.new) end define_method(register_name) { self.class.public_send(register_name) } end |
.register_asset(asset, opts = nil, plugin_directory_name = nil) ⇒ Object
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/discourse_plugin_registry.rb', line 167 def self.register_asset(asset, opts = nil, plugin_directory_name = nil) if asset =~ JS_REGEX if opts == :vendored_pretty_text self.vendored_pretty_text << asset elsif opts == :vendored_core_pretty_text self.vendored_core_pretty_text << asset else self.javascripts << asset end elsif asset =~ /\.css$|\.scss\z/ if opts == :mobile self.mobile_stylesheets[plugin_directory_name] ||= Set.new self.mobile_stylesheets[plugin_directory_name] << asset elsif opts == :desktop self.desktop_stylesheets[plugin_directory_name] ||= Set.new self.desktop_stylesheets[plugin_directory_name] << asset elsif opts == :color_definitions self.color_definition_stylesheets[plugin_directory_name] = asset else self.stylesheets[plugin_directory_name] ||= Set.new self.stylesheets[plugin_directory_name] << asset end end end |
.register_auth_provider(auth_provider) ⇒ Object
131 132 133 |
# File 'lib/discourse_plugin_registry.rb', line 131 def self.register_auth_provider(auth_provider) self.auth_providers << auth_provider end |
.register_html_builder(name, &block) ⇒ Object
211 212 213 214 |
# File 'lib/discourse_plugin_registry.rb', line 211 def self.register_html_builder(name, &block) html_builders[name] ||= [] html_builders[name] << block end |
.register_locale(locale, options = {}) ⇒ Object
157 158 159 |
# File 'lib/discourse_plugin_registry.rb', line 157 def self.register_locale(locale, = {}) self.locales[locale] = end |
.register_mail_poller(mail_poller) ⇒ Object
135 136 137 |
# File 'lib/discourse_plugin_registry.rb', line 135 def self.register_mail_poller(mail_poller) self.mail_pollers << mail_poller end |
.register_modifier(plugin_instance, name, &blk) ⇒ Object
250 251 252 253 254 |
# File 'lib/discourse_plugin_registry.rb', line 250 def self.register_modifier(plugin_instance, name, &blk) @modifiers ||= {} modifiers = @modifiers[name] ||= [] modifiers << [plugin_instance, blk] end |
.register_seed_data(key, value) ⇒ Object
203 204 205 |
# File 'lib/discourse_plugin_registry.rb', line 203 def self.register_seed_data(key, value) self.seed_data[key] = value end |
.register_seed_path_builder(&block) ⇒ Object
207 208 209 |
# File 'lib/discourse_plugin_registry.rb', line 207 def self.register_seed_path_builder(&block) seed_path_builders << block end |
.register_seedfu_filter(filter = nil) ⇒ Object
229 230 231 |
# File 'lib/discourse_plugin_registry.rb', line 229 def self.register_seedfu_filter(filter = nil) self.seedfu_filter << filter end |
.register_service_worker(filename, options = {}) ⇒ Object
144 145 146 |
# File 'lib/discourse_plugin_registry.rb', line 144 def self.register_service_worker(filename, = {}) self.service_workers << filename end |
.register_svg_icon(icon) ⇒ Object
148 149 150 |
# File 'lib/discourse_plugin_registry.rb', line 148 def self.register_svg_icon(icon) self.svg_icons << icon end |
.reset! ⇒ Object
288 289 290 291 |
# File 'lib/discourse_plugin_registry.rb', line 288 def self.reset! @@register_names.each { |name| instance_variable_set(:"@#{name}", nil) } clear_modifiers! end |
.reset_register!(register_name) ⇒ Object
293 294 295 296 297 |
# File 'lib/discourse_plugin_registry.rb', line 293 def self.reset_register!(register_name) found_register = @@register_names.detect { |name| name == register_name } instance_variable_set(:"@#{found_register}", nil) if found_register end |
.seed_paths ⇒ Object
221 222 223 224 225 226 227 |
# File 'lib/discourse_plugin_registry.rb', line 221 def self.seed_paths result = SeedFu.fixture_paths.dup unless Rails.env.test? && ENV["LOAD_PLUGINS"] != "1" seed_path_builders.each { |b| result += b.call } end result.uniq end |
.stylesheets_exists?(plugin_directory_name, target = nil) ⇒ Boolean
192 193 194 195 196 197 198 199 200 201 |
# File 'lib/discourse_plugin_registry.rb', line 192 def self.stylesheets_exists?(plugin_directory_name, target = nil) case target when :desktop self.desktop_stylesheets[plugin_directory_name].present? when :mobile self.mobile_stylesheets[plugin_directory_name].present? else self.stylesheets[plugin_directory_name].present? end end |
.unregister_modifier(plugin_instance, name, &blk) ⇒ Object
256 257 258 259 260 261 262 263 264 265 266 |
# File 'lib/discourse_plugin_registry.rb', line 256 def self.unregister_modifier(plugin_instance, name, &blk) raise "unregister_modifier can only be used in tests" if !Rails.env.test? modifiers_for_name = @modifiers&.[](name) raise "no #{name} modifiers found" if !modifiers_for_name i = modifiers_for_name.find_index { |info| info == [plugin_instance, blk] } raise "no modifier found for that plugin/block combination" if !i modifiers_for_name.delete_at(i) end |
Instance Method Details
#register_archetype(name, options = {}) ⇒ Object
161 162 163 |
# File 'lib/discourse_plugin_registry.rb', line 161 def register_archetype(name, = {}) Archetype.register(name, ) end |
#register_css(filename, plugin_directory_name) ⇒ Object
152 153 154 155 |
# File 'lib/discourse_plugin_registry.rb', line 152 def register_css(filename, plugin_directory_name) self.class.stylesheets[plugin_directory_name] ||= Set.new self.class.stylesheets[plugin_directory_name] << filename end |
#register_js(filename, options = {}) ⇒ Object
139 140 141 142 |
# File 'lib/discourse_plugin_registry.rb', line 139 def register_js(filename, = {}) # If we have a server side option, add that too. self.class.javascripts << filename end |