Developing Discourse Plugins - Part 3 - Add custom site settings

You simply need to add a

config/locales/server.zh_CN.yml

file (and similar for any other locales you want to support) with the same English tokens but with language specific values and the plugin will use that instead of falling back to the English.

2 Likes

Thanks for helping! have a nice day!

3 Likes

I was looking how to create a site setting that validates a username, but found there’s a username type to do this. Here the list of site setting types we have today:

  • email
  • username
  • integer
  • regex
  • string
  • list
  • enum

Also, you can do custom validations for your plugin settings, it accepts a validator field that expects a Ruby class. You use it like this.

plugins:
  my_custom_username_validation:
    default: 'system'
    validator: 'UsernameSettingValidator'

You can check the UsernameSettingValidator class to see the interface of validators.

Cheers!

10 Likes

not working (

<a id="forgot-password-link" class="forgot-password" href="{{Discourse.SiteSettings.myplugin_link_forgot_password}}" target="_blank">Forgot password?</a>

settings.yml

plugins:
  myplugin_enabled:
    default: true
    client: true
  myplugin_link_forgot_password:
    default: ''
    client: true

upd:
working!!!
href="{{unbound siteSettings.myplugin_link_forgot_password}}"

how to display text html ?
not working {{unbound siteSettings.forum_text_for_admin}}

upd:
working in *.hbs {{{unbound siteSettings.forum_text_for_admin}}}

Again you need to use a Computed Property and format as safe html. This is EmberJS not vanilla JavaScript. You can’t put ‘code’ directly into templates. Read the ember guides.

1 Like

already working with EmberJS

I have this in my settings.yml:

plugins:
  county_fence_enabled:
    default: false
    client: true
  county_fence_latrine_category:
    default: -1
    client: true

This shows up in my /admin/plugins page:

I don’t understand why there’s no Settings button?

I think instead of plugins, you are supposed to write the plugin name county_fence.

2 Likes

I have tried that as well, with no difference.

This documentation (as well as OP) uses the plugins key. In other places I have seen the plugin name used, like you have said.

1 Like

@bitmage actually, I might know the reason.

Did you write # name: County Fence in plugin.rb?
If so, the name must be the same as your directory name.

The plugin name can be overwritten from the locale:

Assuming you have this settings format:

county_fence:
  county_fence_enabled: true
  ...

in client.en.yml:

en:
  admin_js:
    admin:
      site_settings:
        categories:
          county_fence: "County Fence"

Setting the default to 0 instead of -1 caused it to show up.

Is there any way to know that a type is not being detected correctly?

  1. YamlLoader loads the file.
  2. SiteSettingExtension calls setting() with the params generated by YamlLoader
  3. …which calls defaults.load_setting then later type_supervisor.load_setting
  4. Even though type_supervisor.load_setting is not directly passed the value, it has access to the defaults because they are being passed in when the TypeSupervisor is initialized via DefaultsProvider.
  5. type_supervisor.load_setting then calls get_data_type which calls parse_value_type() which should raise an ArgumentError if the type cannot be detected.

I think this whole sequence is called by load_settings in the SiteSetting model, and I don’t see any exception handling anywhere in the stack. But I’m not seeing any error output in the server log, or anywhere else.

It seems like there should be some kind of user feedback or error log to say that a setting failed to parse.

If I understand, you’re saying that using -1 as the default value on a setting causes the “Settings” button not to appear. Can you reproduce this behavior every time?

That’s odd. I don’t see anything wrong with your settings, I’m not sure how it’s possible to fail in parsing. :thinking:

Now that it’s working I can change it back to -1 and it continues to function.

I dropped the database, reinitialized and I still can’t reproduce it. :person_shrugging:

1 Like

I’ve deployed the plugin to my live site using the default of 0 just to be safe. The settings button does display:

image

But when I click it no settings are listed:

I will disable the plugin while I continue to troubleshoot this.

Ok, I think in both cases (dev and production) it was because the folder in the plugins directory didn’t match county-fence. That is why the setting was not displaying, and maybe would cause other problems as well.

Thanks folks!

1 Like

It’s unclear to me. Most of the plugins I have installed don’t use plugins:, which includes official and recent plugins (also the skeleton template)

I thought that part was used for the settings filtering, but I might be wrong.

1 Like

Oh interesting! Apologies then.

What I will say is it is not necessary, apparently.

I have lost count of the number of plugins I’ve authored with plugins:

1 Like

To expand on the documentation:

A complete listing of Site Settings types is available in the type_supervisor.rb code. Just above that you can also see the valid child keys that a Site Setting accepts.

A more advanced example which uses more of these options can be found in the discourse-welcome-link theme component. These same values should work inside a plugin, but the file would instead be at config/settings.yml.

3 Likes

There are differences between the plugins and theme component types.

I tried to make a table (expects minor errors or grouping)

Category Functionality Plugin Syntax TC Syntax
Basic Types String type: string
min: ..
max: ..
regex: ..
secret: true/false
global
validator: class name
type: string
min: ..
max: ..
-
-
-
-
Multiline text type: string
textarea: true
type: string
textarea: true
Integer type: integer
min: ..
max: ..
type: integer
min: ..
max: ..
Float type: float
min: ..
max: ..
type: float
min: ..
max: ..
Boolean type: bool type: bool
Time type: time -
Null type: null -
Selection Types Enum (dropdown) type: enum
choices: [option1, option2]
enum: ..
type: enum
choices: [option1, option2]
Category type: category -
Color type: color -
Group type: group -
Email type: email -
Username type: username -
List Types Generic List type: list
allow_any: true/false
type: list
Simple/Compact List type: simple_list
Or
type: list
list_type: compact
list_type: simple
type: list
list_type: compact
list_type: simple
Category List type: category_list type: list
list_type: category
Group List type: group_list type: list
list_type: group
Tag List type: tag_list type: list
list_type: tag
Tag Group List type: tag_group_list -
URL List type: url_list -
Host List type: host_list -
Value List type: value_list -
Emoji List type: emoji_list -
File Types Upload type: upload type: upload
Uploaded Image List type: uploaded_image_list -
File Size Restriction type: file_size_restriction
min: ..
max: ..
-
Special Types HTML (deprecated) type: html_deprecated -
JSON Objects deprecated deprecated
Objects - type: objects
4 Likes