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/
- HANDLEBARS_REGEX =
/\.(hb[rs]|js\.handlebars)\z/
- VENDORED_CORE_PRETTY_TEXT_MAP =
{ "moment.js" => "vendor/assets/javascripts/moment.js", "moment-timezone.js" => "vendor/assets/javascripts/moment-timezone-with-data.js", }
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.
- .each_globbed_asset(each_options = nil) ⇒ Object
- .register_asset(asset, opts = nil, plugin_directory_name = nil) ⇒ Object
- .register_auth_provider(auth_provider) ⇒ Object
- .register_glob(root, extension, options = nil) ⇒ 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
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 |
# File 'lib/discourse_plugin_registry.rb', line 281 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
229 230 231 232 |
# File 'lib/discourse_plugin_registry.rb', line 229 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
256 257 258 259 260 261 |
# File 'lib/discourse_plugin_registry.rb', line 256 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
250 251 252 253 254 |
# File 'lib/discourse_plugin_registry.rb', line 250 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!
38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/discourse_plugin_registry.rb', line 38 def self.define_filtered_register(register_name) define_register(register_name, Array) singleton_class.alias_method :"_raw_#{register_name}", :"#{register_name}" define_singleton_method(register_name) do unfiltered = public_send(:"_raw_#{register_name}") unfiltered.filter { |v| v[:plugin].enabled? }.map { |v| v[:value] }.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!
17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/discourse_plugin_registry.rb', line 17 def self.define_register(register_name, type) @@register_names ||= Set.new @@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 |
.each_globbed_asset(each_options = nil) ⇒ Object
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/discourse_plugin_registry.rb', line 157 def self.each_globbed_asset( = nil) ||= {} self.asset_globs.each do |g| root, ext, = *g if [:admin] next unless [:admin] else next if [:admin] end Dir.glob("#{root}/**/*.#{ext}") { |f| yield f } end end |
.register_asset(asset, opts = nil, plugin_directory_name = nil) ⇒ Object
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/discourse_plugin_registry.rb', line 176 def self.register_asset(asset, opts = nil, plugin_directory_name = nil) if asset =~ JS_REGEX if opts == :admin self.admin_javascripts << asset elsif 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 elsif asset =~ HANDLEBARS_REGEX self. << asset end end |
.register_auth_provider(auth_provider) ⇒ Object
119 120 121 |
# File 'lib/discourse_plugin_registry.rb', line 119 def self.register_auth_provider(auth_provider) self.auth_providers << auth_provider end |
.register_glob(root, extension, options = nil) ⇒ Object
153 154 155 |
# File 'lib/discourse_plugin_registry.rb', line 153 def self.register_glob(root, extension, = nil) self.asset_globs << [root, extension, || {}] end |
.register_html_builder(name, &block) ⇒ Object
224 225 226 227 |
# File 'lib/discourse_plugin_registry.rb', line 224 def self.register_html_builder(name, &block) html_builders[name] ||= [] html_builders[name] << block end |
.register_locale(locale, options = {}) ⇒ Object
145 146 147 |
# File 'lib/discourse_plugin_registry.rb', line 145 def self.register_locale(locale, = {}) self.locales[locale] = end |
.register_mail_poller(mail_poller) ⇒ Object
123 124 125 |
# File 'lib/discourse_plugin_registry.rb', line 123 def self.register_mail_poller(mail_poller) self.mail_pollers << mail_poller end |
.register_modifier(plugin_instance, name, &blk) ⇒ Object
263 264 265 266 267 |
# File 'lib/discourse_plugin_registry.rb', line 263 def self.register_modifier(plugin_instance, name, &blk) @modifiers ||= {} modifiers = @modifiers[name] ||= [] modifiers << [plugin_instance, blk] end |
.register_seed_data(key, value) ⇒ Object
216 217 218 |
# File 'lib/discourse_plugin_registry.rb', line 216 def self.register_seed_data(key, value) self.seed_data[key] = value end |
.register_seed_path_builder(&block) ⇒ Object
220 221 222 |
# File 'lib/discourse_plugin_registry.rb', line 220 def self.register_seed_path_builder(&block) seed_path_builders << block end |
.register_seedfu_filter(filter = nil) ⇒ Object
242 243 244 |
# File 'lib/discourse_plugin_registry.rb', line 242 def self.register_seedfu_filter(filter = nil) self.seedfu_filter << filter end |
.register_service_worker(filename, options = {}) ⇒ Object
132 133 134 |
# File 'lib/discourse_plugin_registry.rb', line 132 def self.register_service_worker(filename, = {}) self.service_workers << filename end |
.register_svg_icon(icon) ⇒ Object
136 137 138 |
# File 'lib/discourse_plugin_registry.rb', line 136 def self.register_svg_icon(icon) self.svg_icons << icon end |
.reset! ⇒ Object
301 302 303 304 |
# File 'lib/discourse_plugin_registry.rb', line 301 def self.reset! @@register_names.each { |name| instance_variable_set(:"@#{name}", nil) } clear_modifiers! end |
.reset_register!(register_name) ⇒ Object
306 307 308 309 310 |
# File 'lib/discourse_plugin_registry.rb', line 306 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
234 235 236 237 238 239 240 |
# File 'lib/discourse_plugin_registry.rb', line 234 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
205 206 207 208 209 210 211 212 213 214 |
# File 'lib/discourse_plugin_registry.rb', line 205 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
269 270 271 272 273 274 275 276 277 278 279 |
# File 'lib/discourse_plugin_registry.rb', line 269 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
149 150 151 |
# File 'lib/discourse_plugin_registry.rb', line 149 def register_archetype(name, = {}) Archetype.register(name, ) end |
#register_css(filename, plugin_directory_name) ⇒ Object
140 141 142 143 |
# File 'lib/discourse_plugin_registry.rb', line 140 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
127 128 129 130 |
# File 'lib/discourse_plugin_registry.rb', line 127 def register_js(filename, = {}) # If we have a server side option, add that too. self.class.javascripts << filename end |