Итак, вы заинтересовались созданием собственной темы для Discourse? Вы попали по адресу ![]()
Это руководство будет сосредоточено в основном на аспектах работы с SCSS/CSS при создании тем для Discourse. Если вы также разбираетесь в JS/EmberJs/Handlebars, вы можете углубиться в тему, изучив это руководство.
Я опишу свой личный метод проектирования и создания тем в Discourse. Как и в большинстве случаев, существует МНОГО способов реализовать собственный дизайн. Я люблю активно использовать инструменты инспектора при создании тем и покажу вам несколько раз, как я это делаю в этом посте.
Настройка для работы с темами
Пожалуйста, прочитайте Руководство для начинающих по использованию тем Discourse, а также Структура тем… перед продолжением. Глубокие знания на этом этапе не обязательны, но эти статьи дадут вам немного больше понимания перед началом работы.
Чтобы максимально эффективно работать с темами в Discourse, я рекомендую настроить следующее для самого быстрого и оптимизированного процесса разработки. Эти шаги позволят вам видеть изменения по мере их внесения, без необходимости «сохранять» и обновлять страницу из панели администратора сайта Discourse.
Вполне возможно пройти это руководство через консоль администратора (при условии, что у вас есть права администратора на форуме Discourse.)
- Установите Discourse Theme CLI и прочитайте соответствующую тему, чтобы понять, что она может делать.
- Получите API-ключ на https://discourse.theme-creator.io/
- Войдите в систему с помощью вашей учетной записи Meta
- Нажмите на Мои темы
- Нажмите на API-ключ
- В появившемся модальном окне нажмите Сгенерировать API-ключ и скопируйте сгенерированный ключ (мы будем использовать его чуть позже)
Запуск Discourse Theme CLI
После установки Discourse Theme CLI и подготовки API-ключа откройте предпочитаемый текстовый редактор или окно терминала и перейдите в директорию, где вы хотите создать папку темы.
После этого выполните следующую команду discourse_theme new your_theme_name и заполните подсказки следующим образом:
-
Как вы хотите назвать свою тему? Выберите название темы
-
Хотите ли вы начать отслеживание этой темы? Да
-
Какой корневой URL вашего сайта Discourse?
https://discourse.theme-creator.io/ -
Хотите сохранить название этого сайта…? Да
-
Какой ваш API-ключ? Введите API-ключ, полученный в Theme Creator
-
Хотите сохранить этот API-ключ…? Да
-
Выберите Создать и синхронизировать новую тему, когда будет предложено
-
Выберите Ничего не делать, когда будет предложено о компонентах дочерних тем
Если всё прошло успешно, вы теперь сможете перейти в раздел Мои темы на https://discourse.theme-creator.io/ и увидеть свою новую тему в списке тем слева.
Чтобы увидеть изменения в реальном времени, нажмите на название вашей темы, а затем в нижней части области информации нажмите на Предпросмотр
Theme CLI также теперь отслеживает любые изменения в созданной директории и будет сохранять, а также обновлять тему на theme-creator при каждом изменении.
Первые шаги
Discourse Theme CLI создал для нас каркас темы внутри папки с именем, которое мы указали в ранее выполненной команде. Сгенерировано много файлов, которые нам не понадобятся, поэтому мы удалим всё, кроме следующего:
common/common.scss
desktop/desktop.scss
mobile/mobile.scss
about.json
Внутри директории также выполните rm -rf .git, чтобы удалить отслеживание версий git, оно не понадобится в этом руководстве.
Ваша директория темы теперь должна выглядеть так:
Стоит отметить, что стили, которые мы добавим в эти файлы, будут применены в соответствующих случаях использования. Стили в common.scss будут применены к десктопной и мобильной версиям, стили в desktop.scss — только к десктопной версии, а стили в mobile.scss — только к мобильной версии.
Hello World (в цвете)
Discourse использует SCSS для стилизации, поэтому для максимальной эффективности работы со стилями вам может быть полезно ознакомиться с SASS, но даже если нет, вы всё равно сможете следовать этому руководству.
Хорошо, теперь перейдём к тому, чего мы все ждали… СОЗДАНИЮ ТЕМ!
Сейчас в нашем файле about.json пока не определено никаких цветовых схем, поэтому вставьте следующий код в этот раздел и сохраните.
{
"name": "my theme",
"about_url": null,
"license_url": null,
"assets": {},
"color_schemes": {
"Default": {
"primary": "222222",
"secondary": "ffffff",
"tertiary": "0088cc",
"quaternary": "e45735",
"header_background": "ffffff",
"header_primary": "333333",
"highlight": "ffff4d",
"danger": "e45735",
"success": "009900",
"love": "fa6c8d"
}
}
}
Если у вас открыт браузер, вы, скорее всего, не заметите никаких изменений, поскольку это цветовая схема по умолчанию, которая используется, когда схема не задана.
Обзор темы
Чтобы было что-то, что можно реализовать в этом руководстве, я проведу вас через создание простой темы на основе этой цветовой палитры.

Изменение цвета фона + основного цвета текста
Давайте сделаем что-то очень простое. Мы изменим значение "Secondary" нашей текущей цветовой схемы. Давайте изменим его на "secondary": "EEF4F7" (это изменит цвет фона). Также изменим значение "primary" на "203243".
Всего одной строкой мы уже изменили внешний вид нашего форума. Много кастомизации можно сделать, просто редактируя цвета в цветовой схеме.
Использование цветовой схемы
Все следующие ключи определены в файле about.json под соответствующим названием цветовой схемы. Эти описания помогут вам понять основное назначение каждого имени переменной:
| Цвет | Описание |
|---|---|
| primary | Большинство текста, иконок и границ |
| secondary | Основной цвет фона и цвет текста некоторых кнопок |
| tertiary | Ссылки, некоторые кнопки, уведомления и акцентный цвет |
| quaternary | Ссылки навигации |
| header_background | Цвет фона заголовка сайта |
| header_primary | Текст и иконки в заголовке сайта |
| highlight | Цвет фона выделенных элементов на странице, таких как сообщения и темы |
| danger | Цвет выделения для действий, таких как удаление сообщений и тем |
| success | Используется для индикации успешного выполнения действия |
| love | Цвет кнопки «Нравится** |
Каждая из этих переменных доступна для использования в наших файлах SCSS следующим образом.
body {
background-color: var(--primary);
}
Также созданы другие версии каждого цвета для нашего использования. Например, var(--primary-medium) или var(--primary-very-low) можно использовать для получения разных оттенков одного и того же цвета.
Давайте изменим остальные цвета в нашей цветовой схеме «Default» в соответствии с этим:
"Default": {
"primary": "203243",
"secondary": "EEF4F7",
"tertiary": "416376",
"quaternary": "5E99B9",
"header_background": "FaFaFa",
"header_primary": "EEF4F7",
"highlight": "86BDDB",
"danger": "8F393E",
"success": "70DB82",
"love": "FC94CB"
}
Вы можете увидеть все доступные переменные для использования в ваших файлах SCSS, если нажмёте на ссылку Стиль во время предпросмотра вашей темы на theme creator, а затем выберете «Цвета» в левом меню.
Раздел «Стиль» очень полезен при создании пользовательской темы. Каждый Атом покажет вам, как будут выглядеть определённые элементы Discourse с применёнными вами стилями.
Углубление
С предыдущим разделом за плечами, думаю, пришло время немного углубиться в то, что можно сделать в Discourse, используя только SCSS. (Подсказка: ОЧЕНЬ МНОГО!)
Стилизация заголовка
Вы заметите, что наши предыдущие изменения цветовой схемы оставили желать лучшего в отношении нашего заголовка. Иконки едва видны!
![]()
Заголовок Discourse включает контейнер (с цветом фона) для размещения логотипа сайта, а также иконок навигации справа. Всё это можно настроить.
Целевой класс для настройки заголовка — .d-header.
В нашем файле common/common.scss добавим следующее:
.d-header {
box-shadow: none;
border-bottom: 1px solid var(--primary-low-mid);
height: 5em;
}
Это уберёт стандартную тень по периметру заголовка, увеличит его высоту, а также добавит нижнюю границу для разделения.
Для иконок — внутри скобок SCSS .d-header добавим этот вложенный код.
.d-header {
// ...предыдущий код
.d-icon {
color: var(--primary-low-mid);
}
}
Выглядит неплохо, но внимательный глаз заметит, что увеличенная высота заголовка оставила меньше места между ним и остальными элементами форума Discourse!
Расстояние между основной областью и заголовком контролируется целевым элементом #main-outlet. Давайте немного увеличим это расстояние, добавив следующее в конец вашего файла common/common.scss.
#main-outlet {
padding-top: 6.5em;
}
Контейнер навигации
Контейнер навигации включает следующие элементы.
![]()
Самая левая область — это выпадающие списки фильтрации по категориям/тегам, за которыми следуют ссылки навигации, завершающиеся кнопкой «Новая тема».
Выпадающий список категорий / тегов
Давайте внесём некоторые изменения в эту область. Для этого добавьте следующее в ваш файл common.scss.
.navigation-container {
.select-kit.combo-box {
.select-kit-header {
border-radius: 0.9em;
background-color: var(--header_background);
}
}
}
Здесь мы нацеливаемся на .select-kit-header, чтобы задать им одинаковый радиус скругления, а также более светлый цвет фона.
Нажатие на любой из них открывает выпадающее меню.
Сейчас у него также острые углы, поэтому давайте добавим стили, чтобы скруглить их, а также изменить цвет фона на тот же, что и у заголовка.
.navigation-container {
.select-kit.combo-box {
// ...предыдущий код
&.category-drop,
&.tag-drop {
.select-kit-body {
border-radius: 0.9em;
background-color: var(--header_background);
.select-kit-collection {
background-color: var(--header_background);
border-top-left-radius: 0px;
border-top-right-radius: 0px;
}
}
}
}
}
В результате получается следующий вид…
Если присмотреться, можно увидеть, что наши изменения оставили видимой небольшую границу в правом верхнем углу области поиска.
Давайте исправим это, заглянув в инспектор браузера. Это всегда очень полезный инструмент для определения классов/ID, на которые нужно нацелиться, чтобы правильно применить стили.
С видимым выпадающим меню щёлкните правой кнопкой мыши по области поиска и выберите «Просмотреть элемент» (Inspect) в браузере.
Мы видим, что это поле ввода находится внутри div с классом select-kit-filter.
Если посмотреть на правила, применяемые к этому селектору, можно увидеть, что у него сейчас есть верхняя и нижняя границы, а также некоторый отступ. Мы хотим изменить только стилизацию верхней границы.
Добавьте следующий код, вложенный в .select-kit-body из предыдущего примера.
.select-kit.combo-box.category-drop,
.select-kit.combo-box.tag-drop {
.select-kit-body {
// ...предыдущий код
.select-kit-filter {
border-top: 0px;
}
}
}
С этим наш код для стилизации контейнера навигации должен выглядеть так.
.navigation-container {
// Выпадающий список категорий + тегов
.select-kit.combo-box {
.select-kit-header {
border-radius: 0.9em;
background-color: var(--header_background);
}
&.category-drop,
&.tag-drop {
.select-kit-body {
border-radius: 0.9em;
background-color: var(--header_background);
.select-kit-collection {
background-color: var(--header_background);
border-top-left-radius: 0px;
border-top-right-radius: 0px;
}
.select-kit-filter {
border-top: 0px;
}
}
}
}
}
Ссылки навигации
Давайте добавим стили, чтобы эти ссылки навигации выглядели примерно так:
![]()
Давайте снова воспользуемся нашим инспектором, чтобы узнать, на что нужно нацелиться здесь.
Мы видим, что наши элементы навигации находятся внутри UL с классом "nav nav-pills ..."
Вернёмся в наш файл common.scss, под предыдущий раздел, но всё ещё внутри navigation-container, и добавим следующее:
.nav-pills {
& > li a {
&.active {
color: var(--tertiary);
background-color: var(--secondary);
border-bottom: 4px solid var(--tertiary);
}
}
}
Это изменение нацелится только на наши ссылки с классом active, которые являются дочерними элементами nav-pills. Это изменение должно сделать нашу активную ссылку похожей на следующее:
![]()
Это нормально, но я бы хотел, чтобы нижняя граница простиралась только на длину текста. Для этого выше строки &.active { добавим следующее, что затронет все ссылки A внутри тегов навигации <li>.
// ...другой код
.nav-pills {
& > li a {
padding: 0;
margin-right: 20px;
color: var(--tertiary-high);
border-bottom: 4px solid transparent;
&.active {
// ...больше кода
}
}
}
Теперь нам нужно стилизовать эффект «наведения» (hover) так же, как эффект «активного» состояния.
Под нашим предыдущим &.active добавим
&:hover {
color: var(--tertiary);
background-color: var(--secondary);
border-bottom: 4px solid var(--primary);
}
Итак, весь наш код навигации теперь должен выглядеть так:
// Nav Pills
.nav-pills {
& > li a {
padding: 0;
margin-right: 20px;
color: var(--tertiary-high);
border-bottom: 4px solid transparent;
&.active {
color: var(--tertiary);
background-color: var(--secondary);
border-bottom: 4px solid var(--tertiary);
}
&:hover {
color: var(--tertiary);
background-color: var(--secondary);
border-bottom: 4px solid var(--primary);
}
}
}
Кнопки
Кнопки в Discourse бывают самых разных форм и размеров. Вы можете просмотреть их ассортимент в разделе «Кнопки» в руководстве по стилю.
Я хотел бы изменить большинство кнопок в этой теме, сделав их скруглёнными с пользовательской стилизацией. Это изменит кнопку + Новая тема, а также другие кнопки по всему сайту.
В конце файла common.scss добавим следующее:
.btn {
background-color: var(--header_background);
color: var(--primary);
border-radius: 1.2em;
border: 1px solid var(--primary-low-mid);
.d-icon {
color: var(--primary);
}
&:hover {
background-color: var(--quaternary-low);
color: var(--primary);
.d-icon {
color: var(--primary);
}
}
&.btn-default,
&.btn-primary {
padding: 10px 12px;
}
}
Это сделает наши кнопки похожими на это:

Теперь, когда наши кнопки стилизованы, я хотел бы обратить внимание на один момент касательно стилизации кнопок и почему важно тестировать все свои дизайны.
Перейдите на страницу любой темы в предпросмотре вашего сайта, затем нажмите кнопку ответить в ответе на тему или в кнопке ответа внизу потока темы. Вы увидите, что наша стилизация кнопок затронула некоторые элементы, которые мы, возможно, не планировали.
Я не хочу, чтобы эти кнопки редактирования текста были затронуты моей предыдущей стилизацией. Это требует более сложного SASS/CSS, но мы можем заставить наш код :not() не затрагивать эти кнопки. ![]()
Давайте добавим эту строку кода перед нашим текущим целевым элементом .btn. Это скажет нашим стилям применяться только к кнопкам, которые не являются дочерними элементами .d-editor-button-bar.
:not(.d-editor-button-bar) > .btn
Хорошо, это сработало отлично… но подождите! Теперь появился какой-то странный бунтарь, делающий своё дело.
![]()
Просмотрев это в браузере, я вижу, что у этой кнопки есть класс .select-kit-header, потому что при нажатии на эту шестерёнку появятся дополнительные опции.
Я не могу подчеркнуть достаточно важность использования инструментов инспектора браузера при создании тем Discourse. Они ваши лучшие друзья в этом путешествии.
Теперь, когда мы знаем, что НЕ хотим нацеливаться на эту кнопку, давайте добавим больше функциональности :not() в наш код.
:not(.d-editor-button-bar) >
.btn:not(.single-select-header)
Это выберет все кнопки, которые НЕ являются дочерними элементами .d-editor-button-bar и не имеют класса .single-select-header. Я знаю, что это немного запутанно, но внутри Discourse много движущихся частей, поэтому иногда стилизация должна быть очень специфичной, чтобы правильно влиять на элементы.
Я также заметил, что наша текущая стилизация неудобно влияет на кнопку закрытия модального окна. Нажав на что-либо, открывающее модальное окно, вы сможете это увидеть, или ещё проще — перейдите в раздел модальных окон в руководстве по стилю.
Чтобы исправить это, я добавлю ещё одну цель в наш код.
:not(.d-editor-button-bar) >
.btn:not(.single-select-header):not(.modal-close)
Продолжаем…
Я вижу ещё одну кнопку, которая, кажется, не была затронута нашим кодом. Это кнопка Отслеживание, расположенная в самом низу потока сообщений темы.

Я добавлю следующую строку через запятую к нашему текущему коду .btn.
:not(.d-editor-button-bar) >
.btn:not(.single-select-header):not(.modal-close),
.topic-notifications-button > .select-kit > .btn
Это правильно нацелится на кнопку, появляющуюся в этом разделе, и на данный момент мы закончили со стилизацией верхней части нашего форума.
Не стесняйтесь настраивать любые параметры в вашем собственном CSS. Чем больше вы экспериментируете со стилями и смотрите, как они влияют на HTML, тем больше вы узнаете!
Куда двигаться дальше
Это руководство предназначено лишь для того, чтобы погрузиться в то, как вы можете кастомизировать свою тему для Discourse. Надеюсь, теперь у вас есть больше понимания о том, как нацеливаться на области приложения для ваших собственных кастомизаций.
Помните: МНОГОЕ можно настроить, используя только SCSS. Если вы хотите углубиться в разработку, я рекомендую прочитать статьи, ссылки на которые приведены в начале этого поста.
Не стесняйтесь задавать любые вопросы, и я с радостью постараюсь помочь вам или направить в правильном направлении.
Этот документ находится под версионным контролем — предлагайте изменения на GitHub.










