FEATURE: Add new plugin API to allow plugins to extend `Site#categories` (#13773)

FEATURE: Add new plugin API to allow plugins to extend Site#categories (#13773)

diff --git a/app/models/site.rb b/app/models/site.rb
index 338091f..4874009 100644
--- a/app/models/site.rb
+++ b/app/models/site.rb
@@ -7,6 +7,14 @@ class Site
   cattr_accessor :preloaded_category_custom_fields
   self.preloaded_category_custom_fields = Set.new
 
+  def self.add_categories_callbacks(&block)
+    categories_callbacks << block
+  end
+
+  def self.categories_callbacks
+    @categories_callbacks ||= []
+  end
+
   def initialize(guardian)
     @guardian = guardian
   end
@@ -104,6 +112,11 @@ class Site
       end
 
       categories.reject! { |c| c[:parent_category_id] && !by_id[c[:parent_category_id]] }
+
+      self.class.categories_callbacks.each do |callback|
+        callback.call(categories)
+      end
+
       categories
     end
   end
diff --git a/lib/plugin/instance.rb b/lib/plugin/instance.rb
index 646603e..de1c833 100644
--- a/lib/plugin/instance.rb
+++ b/lib/plugin/instance.rb
@@ -231,6 +231,17 @@ class Plugin::Instance
     DiscoursePluginRegistry.register_topic_thumbnail_size(size, self)
   end
 
+  # Register a callback to add custom payload to Site#categories
+  # Example usage:
+  #   register_site_categories_callback do |categories|
+  #     categories.each do |category|
+  #       category[:some_field] = 'test'
+  #     end
+  #   end
+  def register_site_categories_callback(&block)
+    Site.add_categories_callbacks(&block)
+  end
+
   def custom_avatar_column(column)
     reloadable_patch do |plugin|
       UserLookup.lookup_columns << column
diff --git a/spec/components/plugin/instance_spec.rb b/spec/components/plugin/instance_spec.rb
index 171e8c9..bdd1c83 100644
--- a/spec/components/plugin/instance_spec.rb
+++ b/spec/components/plugin/instance_spec.rb
@@ -647,4 +647,25 @@ describe Plugin::Instance do
       }.to raise_error(RuntimeError)
     end
   end
+
+  describe '#register_site_categories_callback' do
+    fab!(:category) { Fabricate(:category) }
+
+    it 'adds a callback to the Site#categories' do
+      instance = Plugin::Instance.new
+
+      instance.register_site_categories_callback do |categories|
+        categories.each do |category|
+          category[:test_field] = "test"
+        end
+      end
+
+      site = Site.new(Guardian.new)
+
+      expect(site.categories.first[:test_field]).to eq("test")
+    ensure
+      Site.clear_cache
+      Site.categories_callbacks.clear
+    end
+  end
 end

GitHub sha: a1047f5ef466cffeead9f11a40f487f4d6360eca

This commit appears in #13773 which was approved by lis2. It was merged by tgxworld.