diff --git a/app/controllers/admin/config/site_settings_controller.rb b/app/controllers/admin/config/site_settings_controller.rb index 4dfb9782e1b..58564eaf702 100644 --- a/app/controllers/admin/config/site_settings_controller.rb +++ b/app/controllers/admin/config/site_settings_controller.rb @@ -12,7 +12,7 @@ class Admin::Config::SiteSettingsController < Admin::AdminController # UI itself uses the Admin::SiteSettingsController#index endpoint, # which also supports a `category` and `plugin` filter. def index - if params[:filter_names].blank? && SiteSetting::VALID_AREAS.exclude?(params[:filter_area]) + if params[:filter_names].blank? && SiteSetting.valid_areas.exclude?(params[:filter_area]) raise Discourse::InvalidParameters end diff --git a/lib/discourse_plugin_registry.rb b/lib/discourse_plugin_registry.rb index 6aeb5285c31..7a5e560a686 100644 --- a/lib/discourse_plugin_registry.rb +++ b/lib/discourse_plugin_registry.rb @@ -72,6 +72,7 @@ class DiscoursePluginRegistry define_register :demon_processes, Set define_register :groups_callback_for_users_search_controller_action, Hash define_register :mail_pollers, Set + define_register :site_setting_areas, Set define_filtered_register :staff_user_custom_fields define_filtered_register :public_user_custom_fields diff --git a/lib/plugin/instance.rb b/lib/plugin/instance.rb index df16158651a..01ba645f128 100644 --- a/lib/plugin/instance.rb +++ b/lib/plugin/instance.rb @@ -849,6 +849,14 @@ class Plugin::Instance end end + # Site setting areas are a way to group site settings below + # the setting category level. This is useful for creating focused + # config areas that update a small selection of settings, and otherwise + # grouping related settings in the UI. + def register_site_setting_area(area) + DiscoursePluginRegistry.site_setting_areas << area + end + def javascript_includes assets .map do |asset, opts| diff --git a/lib/site_setting_extension.rb b/lib/site_setting_extension.rb index 95b3df4b798..cd9e7c39cf7 100644 --- a/lib/site_setting_extension.rb +++ b/lib/site_setting_extension.rb @@ -523,6 +523,10 @@ module SiteSettingExtension end end + def valid_areas + Set.new(SiteSetting::VALID_AREAS | DiscoursePluginRegistry.site_setting_areas.to_a) + end + protected def clear_cache! @@ -695,9 +699,9 @@ module SiteSettingExtension if opts[:area] split_areas = opts[:area].split("|") - if split_areas.any? { |area| !SiteSetting::VALID_AREAS.include?(area) } + if split_areas.any? { |area| !SiteSetting.valid_areas.include?(area) } raise Discourse::InvalidParameters.new( - "Area is incorrect. Valid areas: #{SiteSetting::VALID_AREAS.join(", ")}", + "Area is invalid, valid areas are: #{SiteSetting.valid_areas.join(", ")}", ) end areas[name] = split_areas diff --git a/spec/lib/site_setting_extension_spec.rb b/spec/lib/site_setting_extension_spec.rb index ccde4c2a853..f39ca51b293 100644 --- a/spec/lib/site_setting_extension_spec.rb +++ b/spec/lib/site_setting_extension_spec.rb @@ -510,6 +510,17 @@ RSpec.describe SiteSettingExtension do settings.refresh! }.to raise_error(Discourse::InvalidParameters) end + + it "allows plugin to register valid areas" do + plugin = Plugin::Instance.new nil, "/tmp/test.rb" + plugin.register_site_setting_area("plugin_area") + settings.setting(:test_plugin_setting, 88, area: "plugin_area") + expect( + settings + .all_settings(filter_area: "plugin_area", include_locale_setting: false) + .map { |s| s[:setting].to_sym }, + ).to eq(%i[test_plugin_setting]) + end end describe "setting with a validator" do