Custom Topic Filters: URL Params Not Reaching `TopicQuery.options`

While building a plugin with custom topic list filters (e.g., by price, location) using URL query parameters. The URL updates correctly (e.g., ...?market_item_statuses=Available), but the parameters aren’t appearing in topic_query.options on the server.

Setup:

  1. Client-Side Param Registration (tecenc-discovery-params.js):

    // tecenc-discovery-params.js
    import { apiInitializer } from "discourse/lib/api";
    
    export default apiInitializer("1.37.3", (api) => {
      const MARKET_PARAMS_KEYS = [
        "market_price_min", "market_price_max", "market_location",
        "market_conditions", "market_warranty", "market_item_statuses"
      ];
      MARKET_PARAMS_KEYS.forEach(paramKey => {
        api.addDiscoveryQueryParam(paramKey, { replace: true, refreshModel: true });
      });
    });
    
  2. Server-Side Whitelisting Attempt (plugin.rb):

    # plugin.rb
    module ::Tecenc
      MARKET_PARAMS_KEYS = [
        :market_price_min, :market_price_max, :market_location,
        :market_conditions, :market_warranty, :market_item_statuses
      ].freeze
    end
    
    # after_initialize do
      if SiteSetting.tecenc_enabled?
        if defined?(::TopicQuery.add_custom_param_handler)
          ::Tecenc::MARKET_PARAMS_KEYS.each do |param_key|
            ::TopicQuery.add_custom_param_handler(param_key) { |value| value } # Simplified for brevity
          end
          Rails.logger.info "[Tecenc] Registered with add_custom_param_handler."
        elsif defined?(::TopicQuery) && ::TopicQuery.methods.include?(:extra_options_whitelist)
          current_whitelist = ::TopicQuery.extra_options_whitelist || []
          new_whitelist = (current_whitelist + ::Tecenc::MARKET_PARAMS_KEYS).uniq
          ::TopicQuery.extra_options_whitelist(*new_whitelist)
          Rails.logger.info "[Tecenc] Extended extra_options_whitelist."
        else
          Rails.logger.warn "[Tecenc] PLUGIN_WARN: Could not find method to whitelist params for TopicQuery."
        end
    
  3. Server-Side Filtering Logic (plugin.rb):

    # plugin.rb (inside after_initialize / if enabled)
    ::TopicQuery.add_custom_filter(:"tecenc_filters") do |topics, topic_query|
      opts = topic_query.options
      Rails.logger.info "[Tecenc_TopicQuery] Opts: #{opts.inspect}" # CRITICAL LOG
    
      # market_params_present = ::Tecenc::MARKET_PARAMS_KEYS.any? { |p| opts[p].present? }
      # if market_params_present
      #   # ... filtering logic using opts[key] ...
      # end
      topics # or modified_topics
    end
    

The Problem (Logs):

  1. Parameter whitelisting fails:

    [Tecenc] PLUGIN_WARN: Could not find a suitable method (add_custom_param_handler or extra_options_whitelist) to whitelist custom params for TopicQuery.
    
  2. opts in TopicQuery.add_custom_filter is missing our custom params:
    When URL is ...?market_item_statuses=Available, log shows:

    [Tecenc_TopicQuery] Opts: {:category=>5, :filter=>"default", :topic_ids=>nil, :category_id=>5}
    

    Our market_item_statuses (and other custom params) are not present.

Our Environment:

Questions:

  1. What’s the current best practice for ensuring custom URL query params reach topic_query.options in recent Discourse versions?
  2. Why might our attempts to use add_custom_param_handler or extra_options_whitelist be failing with the “Could not find a suitable method” warning?
  3. Is there an alternative approach for parameter registration with TopicQuery we should use?

Any help would be much appreciated!

Just noticed that add_custom_param_handler is not even available as a method on TopicQuery. Is there another way to build custom filters for topics in newer discourse versions?

TopicQuery singleton_methods: [:add_custom_filter, :apply_custom_filters, :new_filter, :public_valid_options, :remove_custom_filter, :remove_muted_tags, :results_filter_callbacks, :results_filter_callbacks=, :tracked_filter, :unread_filter, :valid_options, :validate?, :validators, :yaml_tag]