# Add support for theme settings

**URL:** https://meta.discourse.org/t/add-support-for-theme-settings/78103
**Category:** Feature
**Created:** [January 15, 2018, 10:32pm UTC](https://meta.discourse.org/t/add-support-for-theme-settings/78103 "2018-01-15T22:32:53Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![Osama](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/osama/32/98013_2.png) [@Osama](https://meta.discourse.org/u/Osama)
#### Post date: [January 15, 2018, 10:32pm UTC](https://meta.discourse.org/t/add-support-for-theme-settings/78103/1 "2018-01-15T22:32:53Z")

</div>

Continuing the discussion from [Discourse Tab Bar for Mobile](https://meta.discourse.org/t/discourse-tab-bar-for-mobile/75696/5):

One feature that Discourse doesn’t currently offer is the ability for themes to have some sort of settings or variables that would work similar to how site/plugin settings work i.e. theme settings would be defined with default values by theme developers, and then site owners could override those default values and they’d still be able to get new updates for the theme without worrying about losing their configurations.

#### How should this work?

Obviously this is not complete specifications - this is just a rough idea on how I see this working. I’m keen to hear your ideas and thoughts 🙂

##### a) For site owners

I think all we need to do here is add a simple button somewhere on the theme page. that navigates to a new route `/admin/customize/themes/:theme_id/settings` and the new route will display the settings which will look like this:

 ![interface](https://global.discourse-cdn.com/meta/original/3X/8/b/8bd993032091fcf0406bd3a591111689eb35d464.png)

##### b) For theme developers

I think a new field next to CSS and HTML fields that lets theme developers type their theme settings in YAML (or JSON?) format should do the job. Mockup:

 ![devs](https://global.discourse-cdn.com/meta/original/3X/6/5/65eac51ded6411701e8397de35c39036f7953fb4.png)

(Note “help” is the text that will be displayed below the setting that explains what the setting does)

##### c) Supported data types

I think we should have setting types that support these data types:

Integer  
String  
Boolean  
Enum  
List

##### d) Accessing theme settings in theme JS code

How will theme developers access theme settings in their JS code? I’m thinking something like `Discourse.ThemeSettings.theme_setting_01` but this won’t help with naming collision (when two themes have a setting with the same name) which I’m wondering how should be handled? 🤔

For now that’s all I have. Happy to hear how _you_ see this working 🙂

cc @sam

---

<div class="post-metadata">

### Author: ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)
#### Post date: [January 15, 2018, 10:35pm UTC](https://meta.discourse.org/t/add-support-for-theme-settings/78103/2 "2018-01-15T22:35:05Z")

</div>

I like this but think the vars should be done more like how they are done in the “uploads” section.

Then settings can just show up inline in the front screen.

---

<div class="post-metadata">

### Author: ![j.jaffeux](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/j.jaffeux/32/60297_2.png) [@j.jaffeux](https://meta.discourse.org/u/j.jaffeux)
#### Post date: [January 16, 2018, 8:07am UTC](https://meta.discourse.org/t/add-support-for-theme-settings/78103/3 "2018-01-16T08:07:45Z")

</div>

Just want to add that you probably want to support localisation here.

---

<div class="post-metadata">

### Author: ![Osama](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/osama/32/98013_2.png) [@Osama](https://meta.discourse.org/u/Osama)
#### Post date: [January 16, 2018, 1:16pm UTC](https://meta.discourse.org/t/add-support-for-theme-settings/78103/4 "2018-01-16T13:16:11Z")

</div>

Localisation for the settings help text right? Should we have another field dedicated for translations, or should translations go in the settings field like this 👇?

```yml
setting_01:
    help:
        en: "foo bar"
        fr: "foo bar french"

```

---

<div class="post-metadata">

### Author: ![Osama](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/osama/32/98013_2.png) [@Osama](https://meta.discourse.org/u/Osama)
#### Post date: [February 2, 2018, 10:50pm UTC](https://meta.discourse.org/t/add-support-for-theme-settings/78103/5 "2018-02-02T22:50:10Z")

</div>

PR for this is up:

[https://github.com/discourse/discourse/pull/5562](https://github.com/discourse/discourse/pull/5562)

It works pretty much exactly like the OP describes except for one little thing: I created a separate “Setting” tab for the YAML field instead of nesting it under the Common tab. To me it makes for sense to have its own tab. Open to revert it back if you like the proposal in the OP.

 ![theme-settings-raw](https://global.discourse-cdn.com/meta/original/3X/b/2/b2e1d9975d824259545efd829dc25f1eb268ca72.png)

Screenshot with all supported types:

 ![theme-settings](https://global.discourse-cdn.com/meta/original/3X/1/5/15a30805e0d2b21d1863416aa124aff935f5bdbd.png)

Screenshot when there are no settings (should we omit the settings section?):

 ![image](https://global.discourse-cdn.com/meta/original/3X/f/6/f686b858cd093ee7a811e6b8cbc7c046b44eadd6.png)

---

<div class="post-metadata">

### Author: ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)
#### Post date: [March 5, 2018, 7:26am UTC](https://meta.discourse.org/t/add-support-for-theme-settings/78103/6 "2018-03-05T07:26:14Z")

</div>

This is now merged in! 🤩😍😻

I also implemented the ability consume settings in theme JavaScript like so: [https://github.com/discourse/discourse-linkify-words/blob/master/common/head\_tag.html#L3](https://github.com/discourse/discourse-linkify-words/blob/master/common/head_tag.html#L3) (must be a `type="test/discourse-plugin"`)

@Osama I feel we do need a few refinements if you feel up to it:

Not a huge fan of having this in the UI, I am fine for all the config to happen in the remote git repo. This is very much a feature for ninja theme creators and not the general public.

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

We don’t need this, cause we already have a theme section:

 ![image](https://global.discourse-cdn.com/meta/original/3X/6/1/61c15d4e573414c576114fdb5625b4b73aa7bfcb.png)

Lastly, we need a fancy #howto here explaining how to use it and to update:

> [@Structure of themes and theme components](https://meta.discourse.org/t/how-to-develop-custom-themes/60848):
>
> Discourse supports [native themes](https://meta.discourse.org/t/native-theme-support/47494/26) that can be sourced from a .tar.gz archive or from a remote git repository including [private repositories](https://meta.discourse.org/t/how-to-source-a-theme-from-a-private-git-repository/82584). An example theme is at: [GitHub - discourse/discourse-simple-theme: Sam's simple discourse theme · GitHub](https://github.com/SamSaffron/discourse-simple-theme) The git repository will be checked for updates ([once a day](https://github.com/discourse/discourse/blob/main/app/jobs/scheduled/check_out_of_date_themes.rb)), or by using the Check for Updates button. When changes are detected the Check for Updates button will change to the Update to Latest. [image] To create a theme you need to foll…

If you can give it a shot 💟

---

<div class="post-metadata">

### Author: ![Osama](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/osama/32/98013_2.png) [@Osama](https://meta.discourse.org/u/Osama)
#### Post date: [March 5, 2018, 7:05pm UTC](https://meta.discourse.org/t/add-support-for-theme-settings/78103/7 "2018-03-05T19:05:21Z")

</div>

Here is a PR for the refinements: [UX: Improvements for theme UI by OsamaSayegh · Pull Request #5650 · discourse/discourse · GitHub](https://github.com/discourse/discourse/pull/5650)

> [@sam](#):
>
> Lastly, we need a fancy #howto here explaining how to use it and to update:

I have this on my TODO post-merge list, I’m working on it I’ll try to get it out it by this weekend. ✍

---

<div class="post-metadata">

### Author: ![Osama](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/osama/32/98013_2.png) [@Osama](https://meta.discourse.org/u/Osama)
#### Post date: [March 8, 2018, 4:55am UTC](https://meta.discourse.org/t/add-support-for-theme-settings/78103/8 "2018-03-08T04:55:45Z")

</div>

@sam Is there a reason why the local `settings` JS variable only includes settings that are explicitly used like this `settings.some_setting_name` and doesn’t just include all settings of the theme?

> <https://github.com/discourse/discourse/blob/9331b4849dbcec34057fa76a4cf0f5d98346b155/app/models/theme_field.rb#L32>

To me this looks like it’s not going to cover advanced use-cases where a theme dev would want to do something like this:

```plaintext
settings[`first_${some_variable}_third`]

```

but wouldn’t be able to.

---

<div class="post-metadata">

### Author: ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)
#### Post date: [March 8, 2018, 4:58am UTC](https://meta.discourse.org/t/add-support-for-theme-settings/78103/9 "2018-03-08T04:58:04Z")

</div>

It feels a bit over the top, I did this to cut down on potential bloat if there are lots of settings.

Not against tweaking this, but I got to see a real use case.

---

<div class="post-metadata">

### Author: ![Osama](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/osama/32/98013_2.png) [@Osama](https://meta.discourse.org/u/Osama)
#### Post date: [March 8, 2018, 5:07am UTC](https://meta.discourse.org/t/add-support-for-theme-settings/78103/10 "2018-03-08T05:07:34Z")

</div>

I’ll admit I don’t have a real use-case, I was testing it and noticed that I had to that to be able use my setting. Yeah let’s wait and see if anyone will run into a problem because of this.

---

<div class="post-metadata">

### Author: ![tshenry](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/tshenry/32/119495_2.png) [@tshenry](https://meta.discourse.org/u/tshenry)
#### Post date: [March 8, 2018, 10:24pm UTC](https://meta.discourse.org/t/add-support-for-theme-settings/78103/14 "2018-03-08T22:24:31Z")

</div>

Is there by chance a way to access theme settings in a script of `type="text/x-handlebars"`?

I’ve been able to use `settings.name` to get the value in a script of `type="text/discourse-plugin"` (and it’s awesome I must say!), just wondering if it’s possible to get a setting value in a handlebars script somehow?

I’m still getting my bearings with all of this, so forgive me if there’s something simple I’m missing to handle this 🙂

---

<div class="post-metadata">

### Author: ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)
#### Post date: [March 8, 2018, 11:17pm UTC](https://meta.discourse.org/t/add-support-for-theme-settings/78103/15 "2018-03-08T23:17:53Z")

</div>

Oh yeah … PR completely welcome on this. Just need to figure out how to shuffle the data there. (we can’t do a search replace here, we would have to pass in the setting objects to the context)

---

<div class="post-metadata">

### Author: ![Osama](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/osama/32/98013_2.png) [@Osama](https://meta.discourse.org/u/Osama)
#### Post date: [April 2, 2018, 4:02am UTC](https://meta.discourse.org/t/add-support-for-theme-settings/78103/16 "2018-04-02T04:02:34Z")

</div>

> [@sam](#):
>
> Oh yeah … PR completely welcome on this. Just need to figure out how to shuffle the data there. (we can’t do a search replace here, we would have to pass in the setting objects to the context)

@sam I’m looking into this right now and my plan to go about this is to create a little handlebars helper that would take a key and value as params and inject them into the template context. Then on the server side we get all `text/x-handlebars` scripts and before they’re compiled, we prepend to them something this like for each theme setting:

```plaintext
{{settings-helper context=this key="setting_name" value=setting_value}}

```

Does that sound good to you? Do you think there is a better way to go about this?

---

<div class="post-metadata">

### Author: ![Osama](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/osama/32/98013_2.png) [@Osama](https://meta.discourse.org/u/Osama)
#### Post date: [April 2, 2018, 8:23pm UTC](https://meta.discourse.org/t/add-support-for-theme-settings/78103/17 "2018-04-02T20:23:02Z")

</div>

PR created:

[https://github.com/discourse/discourse/pull/5731](https://github.com/discourse/discourse/pull/5731)

With this change, theme devs will be able to use theme settings in handlebars scripts like so:

```plaintext
<script type='text/x-handlebars' data-template-name='/connectors/discovery-list-container-top/my-template'>
    <div class="test-div">
      {{#if themeSettings.boolean_setting}}
        {{themeSettings.string_setting}}
      {{/if}}
    </div>
</script>

```

---

<div class="post-metadata">

### Author: ![vinothkannans](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/vinothkannans/32/86465_2.png) [@vinothkannans](https://meta.discourse.org/u/vinothkannans)
#### Post date: [April 11, 2018, 7:27pm UTC](https://meta.discourse.org/t/add-support-for-theme-settings/78103/18 "2018-04-11T19:27:05Z")

</div>

> [@Osama](#):
>
> With this change, theme devs will be able to use theme settings in handlebars

It’s not working properly in raw handlebar templates. [Here](https://github.com/discourse/discourse/blob/09c5e1018aba419b10c1123966e6c131efd5b449/app/assets/javascripts/discourse/helpers/theme-setting-injector.es6#L23) incorrect context variable `hash.data.root` is used instead of `hash.hash.context`. But even fixing it not resolving the problem since the context itself carrying incorrect value.

In this [line](https://github.com/discourse/discourse/blob/09c5e1018aba419b10c1123966e6c131efd5b449/app/models/theme_field.rb#L66) instead to set `this` object to `context` variable the [raw handlebar precompiler](https://github.com/discourse/discourse/blob/09c5e1018aba419b10c1123966e6c131efd5b449/app/models/theme_field.rb#L72) setting constant string value `"this"` to the `context` _(`context = "this"`)_. It is working perfectly in normal handlebars since it using [different precompiler](https://github.com/discourse/discourse/blob/09c5e1018aba419b10c1123966e6c131efd5b449/app/models/theme_field.rb#L81).

We have to fix the raw handlebar precompiler to resolve this issue. Until that I did [Remove support for theme settings in raw handlebar templates · discourse/discourse@19e8f9a · GitHub](https://github.com/discourse/discourse/commit/19e8f9af13468080c5e0c2669ee5a2dbef15faee)

---

<div class="post-metadata">

### Author: ![Osama](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/osama/32/98013_2.png) [@Osama](https://meta.discourse.org/u/Osama)
#### Post date: [April 11, 2018, 8:56pm UTC](https://meta.discourse.org/t/add-support-for-theme-settings/78103/19 "2018-04-11T20:56:41Z")

</div>

Ah, apologize about that. It seems my implementation worked in some cases but not all because I tested it by overriding the `list/topic-list-item.raw` template and it worked fine. Could you tell me which raw template my implementation failed to work with so I can debug this further?

---

<div class="post-metadata">

### Author: ![vinothkannans](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/vinothkannans/32/86465_2.png) [@vinothkannans](https://meta.discourse.org/u/vinothkannans)
#### Post date: [April 12, 2018, 8:26am UTC](https://meta.discourse.org/t/add-support-for-theme-settings/78103/20 "2018-04-12T08:26:11Z")

</div>

Yes, after debugging it further I found that not all the raw templates raising the issue. It only happens when a theme include a raw-plugin-outlet connector template. For example when I use the raw plugin outlet [“topic-list-before-status”](https://github.com/discourse/discourse/blob/fda8b3d8793d9097d4b2bfcd6740cf5cc1778cbe/app/assets/javascripts/discourse/templates/list/topic-list-item.raw.hbs#L9) in below theme it breaks the UI.

> <https://github.com/vinothkannans/discourse-test-theme/blob/38caa5dd68ed8fabd5561545a59d22715f8a355f/common/header.html#L1-L3>

So the issue may not be in precompiler. Sorry for my previous misguided reply. But we have to resolve this issue before supporting theme settings for raw templates.

---

<div class="post-metadata">

### Author: ![Osama](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/osama/32/98013_2.png) [@Osama](https://meta.discourse.org/u/Osama)
#### Post date: [April 12, 2018, 5:54pm UTC](https://meta.discourse.org/t/add-support-for-theme-settings/78103/21 "2018-04-12T17:54:03Z")

</div>

There is actually an issue with the precompiler that it doesn’t recognize `this` as the template’s context object. However, I just realized that we don’t really need the precompiler to recognize `this` because the helper function [here](https://github.com/discourse/discourse/blob/09c5e1018aba419b10c1123966e6c131efd5b449/app/assets/javascripts/discourse/helpers/theme-setting-injector.es6#L23) is bound to the template context object, so `this` inside the helper function refers to the template context, which is exactly what we need here. Will put together PR to demonstrate what I mean.

EDIT:

PR sent: [FEATURE: theme settings in RAW hbs templates by OsamaSayegh · Pull Request #5758 · discourse/discourse · GitHub](https://github.com/discourse/discourse/pull/5758) cc @vinothkannans

Tested this change with 4 different scenarios:

- overriding an Ember template
- overriding a raw template
- using a plugin outlet in an Ember template
- using a plugin outlet in a raw template

And it worked in all of them 🎉

---

<div class="post-metadata">

### Author: ![vinothkannans](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/vinothkannans/32/86465_2.png) [@vinothkannans](https://meta.discourse.org/u/vinothkannans)
#### Post date: [May 4, 2018, 1:38pm UTC](https://meta.discourse.org/t/add-support-for-theme-settings/78103/22 "2018-05-04T13:38:16Z")

</div>

Now it’s working fine, thank you @Osama

---

<div class="post-metadata">

### Author: ![erlend\_sh](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/erlend_sh/32/119475_2.png) [@erlend\_sh](https://meta.discourse.org/u/erlend_sh)
#### Post date: [May 4, 2018, 5:09pm UTC](https://meta.discourse.org/t/add-support-for-theme-settings/78103/23 "2018-05-04T17:09:11Z")

</div>

> [@Add settings to your Discourse theme](https://meta.discourse.org/t/add-settings-to-your-discourse-theme/82557):
>
> Discourse has the ability for themes to have “settings” that can be added by theme developers to allow site owners to customize themes through UI without having to change any line of code and worry about losing their changes with future updates for the theme. Themes can also alter certain themeable site settings, for more information on that, see the [Themeable site settings](https://meta.discourse.org/t/-/374376) topic. heavy_plus_sign Adding settings to your theme Adding settings to your theme is a bit different from adding CSS a…
