FEATURE: modifier API for plugins (#20887)

Introduces a new API for plugin data modification without class-based extension overhead.

This commit introduces a new API that allows plugins to modify data in cases where they return different data rather than additional data, as is common with filtered_registers in DiscoursePluginRegistry. This API removes the need for defining class-based extension points.

When a plugin registers a modifier, it will automatically be called if the plugin is enabled. The core will then modify the parameter sent to it using the block registered by the plugin:
 
```ruby
DiscoursePluginRegistry.register_modifier(plugin_instance, :magic_sum_modifier) { |a, b| a + b }
sum = DiscoursePluginRegistry.apply_modifier(:magic_sum_filter, 1, 2)
expect(sum).to eq(3)
```

Key features of these modifiers:

- Operate in a stack (first registered, first called)
- Automatically disabled when the plugin is disabled
- Pass the cumulative result of all block invocations to the caller
This commit is contained in:
Sam
2023-03-30 14:39:55 +11:00
committed by GitHub
parent 4e11014693
commit 795e6d72a4
4 changed files with 99 additions and 0 deletions

View File

@ -258,4 +258,55 @@ RSpec.describe DiscoursePluginRegistry do
)
end
end
context "with filters" do
after { DiscoursePluginRegistry.clear_modifiers! }
class TestFilterPlugInstance < Plugin::Instance
def enabled?
!@disabled
end
def enabled=(value)
@disabled = !value
end
end
let(:plugin_instance) { TestFilterPlugInstance.new }
let(:plugin_instance2) { TestFilterPlugInstance.new }
it "handles modifiers with multiple parameters" do
DiscoursePluginRegistry.register_modifier(plugin_instance, :magic_sum_modifier) do |a, b|
a + b
end
sum = DiscoursePluginRegistry.apply_modifier(:magic_sum_modifier, 1, 2)
expect(sum).to eq(3)
end
it "handles modifier stacking" do
# first in, first called
DiscoursePluginRegistry.register_modifier(plugin_instance, :stacking) { |x| x == 1 ? 2 : 1 }
DiscoursePluginRegistry.register_modifier(plugin_instance2, :stacking) { |x| x + 1 }
expect(DiscoursePluginRegistry.apply_modifier(:stacking, 1)).to eq(3)
end
it "handles disabled plugins" do
plugin_instance.enabled = false
DiscoursePluginRegistry.register_modifier(plugin_instance, :magic_sum_modifier) do |a, b|
a + b
end
sum = DiscoursePluginRegistry.apply_modifier(:magic_sum_modifier, 1, 2)
expect(sum).to eq(1)
end
it "can handle arity mismatch" do
DiscoursePluginRegistry.register_modifier(plugin_instance, :magic_sum_modifier) { 42 }
sum = DiscoursePluginRegistry.apply_modifier(:magic_sum_modifier, 1, 2)
expect(sum).to eq(42)
end
end
end

View File

@ -827,4 +827,17 @@ RSpec.describe Plugin::Instance do
expect(callback_called).to eq(false)
end
end
describe "#register_modifier" do
let(:plugin) { Plugin::Instance.new }
after { DiscoursePluginRegistry.clear_modifiers! }
it "allows modifier registration" do
plugin.register_modifier(:magic_sum_modifier) { |a, b| a + b }
sum = DiscoursePluginRegistry.apply_modifier(:magic_sum_modifier, 1, 2)
expect(sum).to eq(3)
end
end
end