In the last chapter, we created a basic theme via the Discourse admin interface. This works well enough for very simple themes. But as soon as you want to do something more complex, or share a theme more widely, you’ll need to create a Remote Theme.
Install the discourse_theme CLI
The first step towards developing a remote theme is to install the discourse_theme
CLI on your computer. This tool is used to generate the initial scaffold for a theme, and can then synchronize it in real-time to a local Discourse instance, a “production” Discourse community, or the public Theme Creator.
Follow these instructions to install discourse_theme
, then come back here to continue the tutorial.
Create and sync a new theme
In your local terminal, navigate to a directory where you want to store your new theme. Run discourse_theme new my-first-theme
, then follow the prompts to fill in the theme’s metadata.
When setup is done, you’ll see ✅ Done!
, and you’ll be prompted to start “watching” the theme. Answer yes, and then work through the watching setup.
For the root URL, enter the base URL of the Discourse site you’d like to sync the theme to. For a local development environment, use something like http://localhost:4200
. For a production site, use something like https://meta.discourse.org
. Or for Theme Creator, use https://discourse.theme-creator.io
.
Now you’ll need to generate an API key. For a local development environment or production forum, visit the “API Keys” section of the admin panel, choose “Add API key”, and create one associated with your user account, and a “Global” scope. Then paste it into the discourse_theme
CLI.
If you’re using theme creator, visit the themes section of your user profile, click the “API Key” button in the bottom left, generate, then paste into the discourse_theme
CLI.
Finally, choose “Create and Sync with new theme”. You should see a success message, and some handy links to preview and manage the theme.
Right now this is just an empty theme, so let’s add the customizations we created in chapter one of the tutorial to this new theme.
Introducing custom code
Now it’s time to start writing some code! Open up the my-first-theme
directory in your favorite text editor, then find the file inside javascripts/discourse/api-initializers
. Open up the auto-generated .gjs
file and replace the content with the example from the last chapter:
import { apiInitializer } from "discourse/lib/api";
export default apiInitializer("1.8.0", (api) => {
const currentUser = api.getCurrentUser();
api.renderInOutlet(
"discovery-list-container-top",
<template>
<div class="custom-welcome-banner">
{{#if currentUser}}
Welcome back @{{currentUser.username}}
{{else}}
Welcome to our community
{{/if}}
</div>
</template>
);
});
Now open up common/common.scss
, and paste in:
.custom-welcome-banner {
background: green;
color: white;
text-align: center;
padding: 10px;
}
Assuming discourse_theme
is still running in your terminal, these changes will have been synced up to your Discourse site instantly, and reflected in the theme preview. Try tweaking some of the text in the files and watch the result change in the preview.
To start up discourse_theme
’s syncing again without going through the full “new” flow, run discourse_theme watch .
from inside your theme’s directory. Add --reset
if you need to change your forum URL or API key.
Understanding the file structure
As you’ve probably realized, many of the files in the local directory are a 1:1 match to the tabs in the admin panel from chapter 1. For example, common/common.scss
matches the CSS tab, common/after_header.html
matches the After Header tab, and files under javascripts/discourse/api-initializers/*.gjs
are each treated the same as the JS tab.
Along with these, you may have noticed a bunch more placeholder directories & files which have been automatically generated by discourse_theme
. We’ll explore a few of these in more detail later in the tutorial, but you can always find a list of all available files here.
For now, take a look at the about.json
file. This contains the most important metadata for your Remote Theme, including its name, description, author info, and various URLs. This information will be shown to any users of your theme, so it’s important to keep it up-to-date.
Uploading to GitHub
So far you’ve created a local directory and synced it up to a single forum via discourse_theme
. To version-control your theme and make it available for others to install via the Discourse UI, you’ll need to push the directory to an internet-accessible Git repository. We’ll be using GitHub for this tutorial, but any git-hosting platform should work.
First, let’s prepare the local directory. Navigate to the theme in your terminal, then run
git add .
git commit -m "My first commit"
Or if you prefer, perform the commit from your favorite Git user interface.
Then set up the remote repository by visiting github.com/new. Enter a name & description for your repository. Leave the template selection empty, and skip the README, gitignore and license options. Create the repository.
Then follow GitHub’s instructions to “push an existing repository from the command line”. Once complete, you should see all your theme files in the GitHub UI. The repository URL can now be used to install the theme on any Discourse forum, and any updates you push to GitHub will be made available to forum admins.
Now that we’ve got the mechanics out the way, we’ll be exploring a bunch of ways that themes can be used to customize Discourse. Join us in the next chapter.
This document is version controlled - suggest changes on github.