# Developing Discourse Plugins - Part 3 - Add custom site settings

**URL:** https://meta.discourse.org/t/developing-discourse-plugins-part-3-add-custom-site-settings/31115
**Category:** Developer Guides
**Tags:** plugin-guides, tutorial
**Created:** [July 16, 2015, 3:35pm UTC](https://meta.discourse.org/t/developing-discourse-plugins-part-3-add-custom-site-settings/31115 "2015-07-16T15:35:33Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![Discourse](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/discourse/32/148734_2.png) [@Discourse](https://meta.discourse.org/u/Discourse)
#### Post date: [July 16, 2015, 3:35pm UTC](https://meta.discourse.org/t/developing-discourse-plugins-part-3-add-custom-site-settings/31115/1 "2015-07-16T15:35:33Z")

</div>

Previous tutorial: [Developing Discourse Plugins - Part 2 - Connect to a plugin outlet](https://meta.discourse.org/t/developing-discourse-plugins-part-2-connect-to-a-plugin-outlet/31001)

* * *

### Site Settings

If you visit `/admin/site_settings` on a Discourse you have administrator capabilities on, you’ll see a list of configuration settings. Out of the box, we provide what we think are the best settings for a Discourse install, but we also understand that people want to tweak their installations to make their forum just the way they want it.

Chances are, unless your plugin is very simple, you’ll want to add settings that the users of your plugin can change and use to configure functionality. Fortunately, this is quite easy to do!

### `config/settings.yml`

The first thing you’ll need to do is create `config/settings.yml` within your plugin folder. This file will outline all the settings your plugin will need. Here’s an example file:

```yaml
plugins:
  awesomeness_enabled:
    default: true
    client: true
  awesomeness_max_volume:
    default: 10
    client: true

```

The file needs to be in [YAML](https://en.wikipedia.org/wiki/YAML) format. YAML can be quite picky so if Discourse is having trouble loading your settings I suggest you try validating your YAML with a tool like [YAMLint](http://www.yamllint.com/).

I’ll explain the example file in detail. The top level is `plugins` and that tells Discourse that we want these settings to appear under “Plugins” in the site settings.

After that, there are two settings declared, `awesomeness_enabled` and `awesomeness_max_volume`. Discourse reasons the type of the settings from the default, so `awesomeness_enabled` is a boolean and `awesomeness_max_volume` is a number.

The `client: true` is important to understand. Discourse is made up of two major applications, the server side API written in Ruby on Rails, and the client side application written in Ember.js. By default, we don’t expose settings to the Ember.js client app unless you add `client: true`. We do this because some settings are private like API keys and should not be sent to end users. Also, if we sent every setting to the client that could be a lot for end users to download!

In our example case, we want both of those settings to be accessible in the JavaScript world as well as the server side world.

### An important second step

Before you can use your newly added site settings, you need to add translations for them. Since Discourse supports many languages, any text you add will have to support being translated into other languages.

Let’s create the translations for our settings in English:

**`config/locales/server.en.yml`**

```yaml
en:
  site_settings:
    awesomeness_enabled: "Is this plugin awesome?"
    awesomeness_max_volume: "What is the maximum volume possible?"

```

The labels we added in that file will be displayed in the admin section. It’s a good idea to be clear as possible as to what the setting accomplishes.

### Declaring the setting as the ‘enabled setting’

Now that we have our site setting, we should tell Discourse that it’s the one that turns our features on and off.

Open your `plugin.rb` file and add the following line below the metadata comments:

```rb
enabled_site_setting :awesomeness_enabled

```

Make sure to start all of your other settings with “`awesomeness_`” in order for the settings button at `/admin/plugins` to work correctly.

### Accessing your new Settings

First, you’ll need to restart your development server to have the settings take effect. Once you do that, the settings should be available to your server and client side code.

We automatically inject the site settings into most JavaScript objects, so if you are declaring a `Component`, `Controller`, `Route`, `View` or `Model` you should be able to access the site setting by simply using `this.siteSettings.awesomeness_enabled`. In most handlebars templates you should also be able to say `{{siteSettings.awesomeness_enabled}}` and the setting value will be displayed.

We haven’t covered much Ruby stuff in this series yet, but if you want to access the site settings in the Ruby application you can do so via: `SiteSetting.awesomeness_enabled`

Now go forth and add custom settings to your plugins!

* * *

### More in the series

Part 1: [Plugin Basics](https://meta.discourse.org/t/beginners-guide-to-creating-discourse-plugins-part-1/30515)  
Part 2: [Plugin Outlets](https://meta.discourse.org/t/beginners-guide-to-creating-discourse-plugins-part-2-plugin-outlets/31001)  
**Part 3: This topic**  
Part 4: [git setup](https://meta.discourse.org/t/beginners-guide-to-creating-discourse-plugins-part-4-git-setup/31272)  
Part 5: [Admin interfaces](https://meta.discourse.org/t/beginners-guide-to-creating-discourse-plugins-part-5-admin-interfaces/31761)  
Part 6: [Acceptance tests](https://meta.discourse.org/t/beginner-s-guide-to-creating-discourse-plugins-part-6-acceptance-tests/32619)  
Part 7: [Publish your plugin](https://meta.discourse.org/t/beginner-s-guide-to-creating-discourse-plugins-part-7-publish-your-plugin/101636)

* * *

This document is version controlled - suggest changes [on github](https://github.com/discourse/discourse/blob/main/docs/developer-guides/docs/04-plugins/03-site-settings.md).

---

<div class="post-metadata">

### Author: ![rewphus](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/rewphus/32/115836_2.png) [@rewphus](https://meta.discourse.org/u/rewphus)
#### Post date: [July 30, 2015, 12:21am UTC](https://meta.discourse.org/t/developing-discourse-plugins-part-3-add-custom-site-settings/31115/2 "2015-07-30T00:21:15Z")

</div>

For those more familiar with YAML, this was probably obvious, and thanks to [YAMLint](http://www.yamllint.com/) that you referenced I was able to figure this out pretty quick, but I thought it was worth mentioning that the format for the **config/locales/server.en.yml** needs to specifically be:

```plaintext
en:
  site_settings:
    awesomeness_enabled: "Is this plugin awesome?"
    max_volume: "What is the maximum volume possible?"

```

Correct?

Another quick question, it’s great that I can get to the settings by clicking on the `Change Settings` button, but how do I get the plugin specific `Settings` button directly to the right of the plugin like the poll plugin?

[https://s3.amazonaws.com/f.cl.ly/items/162n220f0M0P3e0j2U3M/Image%202015-07-29%20at%207.29.28%20PM.png](https://s3.amazonaws.com/f.cl.ly/items/162n220f0M0P3e0j2U3M/Image%202015-07-29%20at%207.29.28%20PM.png)

Or is that a little too much for a Beginner’s Guide?

---

<div class="post-metadata">

### Author: ![riking](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/riking/32/170938_2.png) [@riking](https://meta.discourse.org/u/riking)
#### Post date: [July 30, 2015, 2:36am UTC](https://meta.discourse.org/t/developing-discourse-plugins-part-3-add-custom-site-settings/31115/3 "2015-07-30T02:36:41Z")

</div>

I updated the guide to fix both of those 😄

---

<div class="post-metadata">

### Author: ![cpradio](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/cpradio/32/4970_2.png) [@cpradio](https://meta.discourse.org/u/cpradio)
#### Post date: [August 16, 2015, 5:15pm UTC](https://meta.discourse.org/t/developing-discourse-plugins-part-3-add-custom-site-settings/31115/4 "2015-08-16T17:15:43Z")

</div>

How do you get the settings button to pre-populate the search field like Discourse Tagging does? I feel like I’m missing something obvious.

**Edit:** Nevermind, I figured it out. You had to use \*\_enabled to get it to filter. I originally didn’t have an enabled setting because the URL was simply the factor for determining if it is enabled.

---

<div class="post-metadata">

### Author: ![tgxworld](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/tgxworld/32/106117_2.png) [@tgxworld](https://meta.discourse.org/u/tgxworld)
#### Post date: [August 20, 2015, 12:59pm UTC](https://meta.discourse.org/t/developing-discourse-plugins-part-3-add-custom-site-settings/31115/5 "2015-08-20T12:59:17Z")

</div>

> [@eviltrout](#):
>
> In most handlebars templates you should also be able to say {{siteSettings.awesomeness\_enabled}} and the setting value will be displayed.

For some reason, `{{siteSettings}}` in the `poster-name-right` outlet returns `undefined`. I tested with other outlets and the return the expected value. I’m not sure why :sadpanda:

Had to work around it by using `{{Discourse.SiteSettings}}`

---

<div class="post-metadata">

### Author: ![eviltrout](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/eviltrout/32/5275_2.png) [@eviltrout](https://meta.discourse.org/u/eviltrout)
#### Post date: [August 20, 2015, 3:08pm UTC](https://meta.discourse.org/t/developing-discourse-plugins-part-3-add-custom-site-settings/31115/6 "2015-08-20T15:08:00Z")

</div>

This isn’t working because the `Post` view code path is some of the oldest code we have and it doesn’t do all the automatic stuff newer code can do ☹

I’ve come up with a fix that I think will solve your problem:

[https://github.com/discourse/discourse/commit/11d1619e2c5239dd5f7fb1446c313e13a60fc26d](https://github.com/discourse/discourse/commit/11d1619e2c5239dd5f7fb1446c313e13a60fc26d)

In the future I’ll be able to remove this hack and it’ll just work.

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [September 28, 2015, 3:44pm UTC](https://meta.discourse.org/t/developing-discourse-plugins-part-3-add-custom-site-settings/31115/7 "2015-09-28T15:44:29Z")

</div>

Hey @eviltrout how can I add a user setting? I mean a setting for a plugin that every user can change on his profile? Can I set a default too?

I guess is the same as an Custom User Field, so can I create a new User Field from a plugin?

---

<div class="post-metadata">

### Author: ![eviltrout](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/eviltrout/32/5275_2.png) [@eviltrout](https://meta.discourse.org/u/eviltrout)
#### Post date: [September 28, 2015, 3:59pm UTC](https://meta.discourse.org/t/developing-discourse-plugins-part-3-add-custom-site-settings/31115/8 "2015-09-28T15:59:22Z")

</div>

> [@Falco](#):
>
> so can I create a new User Field from a plugin?

Unfortunately there’s no easy way to do this right now. There is probably a good argument to be made for such an API for plugin authors.

Until then the way to do it is to add the fields via plugin outlets to the user preferences, tap into serializers and saving logic to store the setting the `PluginStore`.

---

<div class="post-metadata">

### Author: ![tgxworld](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/tgxworld/32/106117_2.png) [@tgxworld](https://meta.discourse.org/u/tgxworld)
#### Post date: [September 30, 2015, 3:28am UTC](https://meta.discourse.org/t/developing-discourse-plugins-part-3-add-custom-site-settings/31115/9 "2015-09-30T03:28:03Z")

</div>

I ran into this a while back too. We have to expose the field in the site settings too. I’ll see if I can add a PR to make this easier.

> <https://github.com/discourse/discourse-cakeday/blob/14c902199a236026c3c67a3f99027fe063226363/plugin.rb#L11-L31>

---

<div class="post-metadata">

### Author: ![jamesmarkcook](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jamesmarkcook/32/168563_2.png) [@jamesmarkcook](https://meta.discourse.org/u/jamesmarkcook)
#### Post date: [February 14, 2016, 7:27pm UTC](https://meta.discourse.org/t/developing-discourse-plugins-part-3-add-custom-site-settings/31115/10 "2016-02-14T19:27:38Z")

</div>

For anyone following this tutorial and trying to get `SiteSettings.awesomeness_enabled` to return anything in a rails console, be aware that the tutorial is wrong. It should be `SiteSetting.awesomeness_enabled` (`Setting` without the `s` at the end!)

---

<div class="post-metadata">

### Author: ![Mittineague](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/mittineague/32/114259_2.png) [@Mittineague](https://meta.discourse.org/u/Mittineague)
#### Post date: [February 14, 2016, 8:43pm UTC](https://meta.discourse.org/t/developing-discourse-plugins-part-3-add-custom-site-settings/31115/11 "2016-02-14T20:43:40Z")

</div>

> [@jamesmarkcook](#):
>
> Setting without the s at the en

Hmmm, this works for me in the hbs files

```plaintext
{{#if siteSettings.plugin_outlet_locations_enabled}}

```

Different syntax depending on where it’s being called from?

EDIT  
Ah, the singular - plural Rails “magic” thing.

---

<div class="post-metadata">

### Author: ![riking](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/riking/32/170938_2.png) [@riking](https://meta.discourse.org/u/riking)
#### Post date: [February 14, 2016, 11:17pm UTC](https://meta.discourse.org/t/developing-discourse-plugins-part-3-add-custom-site-settings/31115/12 "2016-02-14T23:17:40Z")

</div>

Nope, your first guess was correct \>.\>

JS has Discourse.SiteSettings but Rails has SiteSetting.

---

<div class="post-metadata">

### Author: ![eviltrout](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/eviltrout/32/5275_2.png) [@eviltrout](https://meta.discourse.org/u/eviltrout)
#### Post date: [February 16, 2016, 3:22pm UTC](https://meta.discourse.org/t/developing-discourse-plugins-part-3-add-custom-site-settings/31115/13 "2016-02-16T15:22:12Z")

</div>

Oops! Thanks for letting me know. I’ve updated the tutorial.

---

<div class="post-metadata">

### Author: ![fantasticfears](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/fantasticfears/32/119608_2.png) [@fantasticfears](https://meta.discourse.org/u/fantasticfears)
#### Post date: [March 16, 2016, 8:33am UTC](https://meta.discourse.org/t/developing-discourse-plugins-part-3-add-custom-site-settings/31115/14 "2016-03-16T08:33:11Z")

</div>

> [@eviltrout](#):
>
> Make sure to start all of your other settings with “awesomeness\_” in order for the settings button at /admin/plugins to work correctly.

Well, I believe some infrastructure are not complete yet. But I am refurnishing old login plugins while it’s worthwhile to asking the future change to plugin infra. Shall I move settings from `login` to plugin prefix?

---

<div class="post-metadata">

### Author: ![eviltrout](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/eviltrout/32/5275_2.png) [@eviltrout](https://meta.discourse.org/u/eviltrout)
#### Post date: [March 16, 2016, 3:14pm UTC](https://meta.discourse.org/t/developing-discourse-plugins-part-3-add-custom-site-settings/31115/15 "2016-03-16T15:14:32Z")

</div>

I would recommend to do that, yes.

---

<div class="post-metadata">

### Author: ![mcwumbly](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/mcwumbly/32/103861_2.png) [@mcwumbly](https://meta.discourse.org/u/mcwumbly)
#### Post date: [May 9, 2016, 1:37am UTC](https://meta.discourse.org/t/developing-discourse-plugins-part-3-add-custom-site-settings/31115/16 "2016-05-09T01:37:05Z")

</div>

> [@eviltrout](#):
>
> We automatically inject the site settings into most Javascript objects

Just to clarify, this is only the case if you say `client: true`, right?

---

<div class="post-metadata">

### Author: ![eviltrout](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/eviltrout/32/5275_2.png) [@eviltrout](https://meta.discourse.org/u/eviltrout)
#### Post date: [May 9, 2016, 2:48pm UTC](https://meta.discourse.org/t/developing-discourse-plugins-part-3-add-custom-site-settings/31115/17 "2016-05-09T14:48:40Z")

</div>

Yes, that is correct. Javascript gets access to the “client side” site settings.

---

<div class="post-metadata">

### Author: ![Bolarinwa\_Balogun](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/bolarinwa_balogun/32/138753_2.png) [@Bolarinwa\_Balogun](https://meta.discourse.org/u/Bolarinwa_Balogun)
#### Post date: [February 15, 2018, 5:13pm UTC](https://meta.discourse.org/t/developing-discourse-plugins-part-3-add-custom-site-settings/31115/18 "2018-02-15T17:13:52Z")

</div>

> [@eviltrout](#):
>
> By default, we don’t expose settings to the Ember.js client app unless you add client: true.

I do not completely understand this statement. I set it to client: false but it was still visible in admin settings. What exactly happens if you set client to false.

Thank you.

---

<div class="post-metadata">

### Author: ![eviltrout](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/eviltrout/32/5275_2.png) [@eviltrout](https://meta.discourse.org/u/eviltrout)
#### Post date: [February 15, 2018, 6:44pm UTC](https://meta.discourse.org/t/developing-discourse-plugins-part-3-add-custom-site-settings/31115/19 "2018-02-15T18:44:14Z")

</div>

We ship up a big JSON object of all the site settings that have `client: true` to all users, so those are considered public and viewable.

If they don’t have `client: true` then they are meant to be available from the server side. The admin section is an exception - we need to return all site settings to admin users so they can be changed! It uses a different API to get them all.

---

<div class="post-metadata">

### Author: ![1c7](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/1c7/32/94822_2.png) [@1c7](https://meta.discourse.org/u/1c7)
#### Post date: [April 28, 2018, 9:23am UTC](https://meta.discourse.org/t/developing-discourse-plugins-part-3-add-custom-site-settings/31115/20 "2018-04-28T09:23:23Z")

</div>

Work for me! 2018-4-28

## Code

`config/settings.yml`

 ![image](https://global.discourse-cdn.com/meta/original/3X/d/8/d8e61ddb2207d6f5eddcc53345f1197b9a7443b1.png)

`config/locales/server.en.yml`

 ![image](https://global.discourse-cdn.com/meta/original/3X/a/d/ad23735619b645e1c21c22b5d70cad0d79a6b998.png)

`plugin.rb`

 ![image](https://global.discourse-cdn.com/meta/original/3X/1/0/10723de7127180cf1bc8e113313c54489631f176.png)

## Result

[http://localhost:3000/admin/site\_settings/category/plugins](http://localhost:3000/admin/site_settings/category/plugins)

 ![image](https://global.discourse-cdn.com/meta/original/3X/5/8/58738735996caba9083d058aea69787a2a276919.png)  
(oh, I saw the translation missing hint)

Thanks!

[Next page](https://meta.discourse.org/t/developing-discourse-plugins-part-3-add-custom-site-settings/31115.md?page=2)
