Dependent Plugin Settings are ... AWESOME!

Oh … this is really :chefs_kiss:

Allow me to illustrate.

Here’s a selector in the latest version of Chatbot, notice it is in “off” state:

Now let’s change that selection:

and it reveals as if by :sparkles: settings that only need to be considered when that value is selected.

This is a really fantastic way of reducing unnecessary clutter in plugin settings and making things simpler to set up with less cognitive load :tada:

Daniel Labelle's Fast Cleaning Challenge

8 Likes

jaw drops I’ve been waiting for something like this for a really loooong time. scrambles to check the repo Are there any docs on this?

1 Like

Feel free to use Chatbot use as a helpfulish example of using it:

and I’m sure there are a bunch of uses in core by now …

1 Like

There is documentation, but it is currently afaia fragmented rather than presented as a standalone developer guide.

The main authoritative references are:

  • Schema documentation in config/site_settings.yml:52, covering depends_on, depends_on_values, depends_behavior, and dependent_setting_display.

  • More detailed guidance and examples in .skills/discourse-site-settings/SKILL.md:203.

  • Backend behaviour specs in spec/lib/site_setting_extension_spec.rb:706.

  • Frontend dependency resolution in frontend/discourse/admin/services/admin-site-setting-store.js:41.

  • UI examples in frontend/discourse/tests/acceptance/admin-site-settings-test.js:142.

The basic syntax is:

child_setting:
  default: ""
  depends_on:
     - parent_setting
  depends_behavior: "hidden"

For enum or string parents:

 child_setting:
    default: ""
    depends_on:
      - parent_setting
    depends_on_values:
      parent_setting:
        - enabled_mode
        - another_mode
    depends_behavior: "hidden"
    dependent_setting_display: "inline"

One important limitation: dependencies can contain multiple direct parents, but dependency resolution is not transitive. A nested chain such as A → B → C does not automatically make C consider whether B is itself hidden by A; C only evaluates B’s stored value.

3 Likes