Theme Developer Quick Reference Guide

As themes grow more powerful, there’s more to remember about how they work. We have loads of detailed documentation under #howto / #themes, but if you just need something to jog your memory, this guide may help.

General Resources

:scroll: Beginner’s guide

:scroll: Developer’s guide

:paintbrush: Theme Creator

:desktop_computer: Theme CLI

:notebook_with_decorative_cover: Theme Directory

File/Folder Structure read more

about.json
settings.yml
common/, desktop/, mobile/
  {common|desktop|mobile}.scss
  head_tag.html
  header.html
  after_header.html
  body_tag.html
  footer.html
  embedded.scss (common only)
locales/
  en.yml
  ...
assets/
  (arbitrarily named files, referenced in about.json)
stylesheets/
  (arbitrarily named files, can be imported from each other, and common/desktop/mobile.scss)
javascripts/
  (arbitrarily named files. Supports .js.es6 .hbs and .raw.hbs)

about.json structure info, available metadata

{
  "name": "My Theme",
  "component": false,
  "license_url": null,
  "about_url": null,
  "authors": null,
  "theme_version": null,
  "minimum_discourse_version": null, 
  "maximum_discourse_version": null,
  "assets": {
    "variable-name": "assets/my-asset.jpg"
  },
  "color_schemes": {
    "My Colour Scheme": {
      "primary": "222222",
    }
  }
}

Javascript read more

<!-- Define in </head> section of theme-->
<script type="text/discourse-plugin" version="0.8">
    console.log("I am ", api.getCurrentUser().username);
</script>

:link: JS Plugin API

:link: Multi-file Javascript

Templates read more

<!-- Define in </head> section of theme-->

<!-- Plugin Outlet -->
<script type="text/x-handlebars" data-template-name="/connectors/below-footer/arbitrary-unique-name">
   This is displayed below the footer
</script>

<!-- Override Core -->
<script type="text/x-handlebars" data-template-name="list/topic-list-item.raw">
   This used to be a topic list item
</script>

:link: Locate outlets

Settings read more

settings.yml:

whitelisted_fruits:
  default: apples|oranges
  type: list
  description: # Old method. It's better to define these in the locale files (see below)
    en: English Description
    fr: Description Française

Access from JavaScript:

console.log(settings.whitelisted_fruits);

Access from templates:

{{theme-setting "whitelisted_fruits"}}

Translations read more

locales/en.yml

en: 
  my_translation_key: "I love themes"
  theme_metadata: # These are used in the admin panel. They are not made available to your js/hbs files
    description: This theme lets you do amazing things on your Discourse
    settings:
      whitelisted_fruits: A description of the whitelisted_fruits setting

Access from JavaScript:

I18n.t(themePrefix("my_translation_key"))

Access from templates:

{{theme-i18n "my_translation_key"}}
{{d-button label=(theme-prefix "my_translation_key")}}
19 Likes