Руководство дизайнера по началу работы с темами в Discourse

Итак, вы заинтересовались созданием собственной темы для Discourse? Вы попали по адресу :smile:

Это руководство будет сосредоточено в основном на аспектах работы с 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 и заполните подсказки следующим образом:

  1. Как вы хотите назвать свою тему? Выберите название темы

  2. Хотите ли вы начать отслеживание этой темы? Да

  3. Какой корневой URL вашего сайта Discourse? https://discourse.theme-creator.io/

  4. Хотите сохранить название этого сайта…? Да

  5. Какой ваш API-ключ? Введите API-ключ, полученный в Theme Creator

  6. Хотите сохранить этот API-ключ…? Да

  7. Выберите Создать и синхронизировать новую тему, когда будет предложено

  8. Выберите Ничего не делать, когда будет предложено о компонентах дочерних тем

Если всё прошло успешно, вы теперь сможете перейти в раздел Мои темы на 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"
    }
  }
}

Если у вас открыт браузер, вы, скорее всего, не заметите никаких изменений, поскольку это цветовая схема по умолчанию, которая используется, когда схема не задана.

Обзор темы

Чтобы было что-то, что можно реализовать в этом руководстве, я проведу вас через создание простой темы на основе этой цветовой палитры.

image

Изменение цвета фона + основного цвета текста

Давайте сделаем что-то очень простое. Мы изменим значение "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"
    }

:flashlight: Вы можете увидеть все доступные переменные для использования в ваших файлах SCSS, если нажмёте на ссылку Стиль во время предпросмотра вашей темы на theme creator, а затем выберете «Цвета» в левом меню.

Раздел «Стиль» очень полезен при создании пользовательской темы. Каждый Атом покажет вам, как будут выглядеть определённые элементы Discourse с применёнными вами стилями.

Углубление

С предыдущим разделом за плечами, думаю, пришло время немного углубиться в то, что можно сделать в Discourse, используя только SCSS. (Подсказка: ОЧЕНЬ МНОГО!)

Стилизация заголовка

Вы заметите, что наши предыдущие изменения цветовой схемы оставили желать лучшего в отношении нашего заголовка. Иконки едва видны!

image

Заголовок 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;
}

Контейнер навигации

Контейнер навигации включает следующие элементы.

image

Самая левая область — это выпадающие списки фильтрации по категориям/тегам, за которыми следуют ссылки навигации, завершающиеся кнопкой «Новая тема».

Выпадающий список категорий / тегов

Давайте внесём некоторые изменения в эту область. Для этого добавьте следующее в ваш файл 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;
        }
      }
    }
  }
}

Ссылки навигации

Давайте добавим стили, чтобы эти ссылки навигации выглядели примерно так:

image

Давайте снова воспользуемся нашим инспектором, чтобы узнать, на что нужно нацелиться здесь.

Мы видим, что наши элементы навигации находятся внутри 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. Это изменение должно сделать нашу активную ссылку похожей на следующее:

image

Это нормально, но я бы хотел, чтобы нижняя граница простиралась только на длину текста. Для этого выше строки &.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;
  }
}

Это сделает наши кнопки похожими на это:

image

Теперь, когда наши кнопки стилизованы, я хотел бы обратить внимание на один момент касательно стилизации кнопок и почему важно тестировать все свои дизайны.

Перейдите на страницу любой темы в предпросмотре вашего сайта, затем нажмите кнопку ответить в ответе на тему или в кнопке ответа внизу потока темы. Вы увидите, что наша стилизация кнопок затронула некоторые элементы, которые мы, возможно, не планировали.

Я не хочу, чтобы эти кнопки редактирования текста были затронуты моей предыдущей стилизацией. Это требует более сложного SASS/CSS, но мы можем заставить наш код :not() не затрагивать эти кнопки. :wink:

Давайте добавим эту строку кода перед нашим текущим целевым элементом .btn. Это скажет нашим стилям применяться только к кнопкам, которые не являются дочерними элементами .d-editor-button-bar.

:not(.d-editor-button-bar) > .btn

Хорошо, это сработало отлично… но подождите! Теперь появился какой-то странный бунтарь, делающий своё дело.

image

Просмотрев это в браузере, я вижу, что у этой кнопки есть класс .select-kit-header, потому что при нажатии на эту шестерёнку появятся дополнительные опции.

:flashlight: Я не могу подчеркнуть достаточно важность использования инструментов инспектора браузера при создании тем 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)

Продолжаем…

Я вижу ещё одну кнопку, которая, кажется, не была затронута нашим кодом. Это кнопка Отслеживание, расположенная в самом низу потока сообщений темы.

image

Я добавлю следующую строку через запятую к нашему текущему коду .btn.

:not(.d-editor-button-bar) >
.btn:not(.single-select-header):not(.modal-close),
.topic-notifications-button > .select-kit > .btn

Это правильно нацелится на кнопку, появляющуюся в этом разделе, и на данный момент мы закончили со стилизацией верхней части нашего форума.

:flashlight: Не стесняйтесь настраивать любые параметры в вашем собственном CSS. Чем больше вы экспериментируете со стилями и смотрите, как они влияют на HTML, тем больше вы узнаете!

Куда двигаться дальше

Это руководство предназначено лишь для того, чтобы погрузиться в то, как вы можете кастомизировать свою тему для Discourse. Надеюсь, теперь у вас есть больше понимания о том, как нацеливаться на области приложения для ваших собственных кастомизаций.

Помните: МНОГОЕ можно настроить, используя только SCSS. Если вы хотите углубиться в разработку, я рекомендую прочитать статьи, ссылки на которые приведены в начале этого поста.

Не стесняйтесь задавать любые вопросы, и я с радостью постараюсь помочь вам или направить в правильном направлении.


Этот документ находится под версионным контролем — предлагайте изменения на GitHub.

44 лайка

Привет, @jordan.vidrine,

При работе над разделом Запуск CLI темы Discourse этого руководства я столкнулся с ошибкой 301.

Мне удалось её исправить, используя https://discourse.theme-creator.io/ вместо https://theme-creator.discourse.org в качестве корневого URL.

Надеюсь, это поможет!

7 лайков

О да, мы обновили этот URL, и этот пост тоже требует обновления — спасибо, что сообщили нам!

6 лайков

Спасибо за эту информацию, @IdentityDan!
Также для справки: если вы столкнулись с этой ошибкой, вам, скорее всего, потребуется отредактировать файл /home/USERNAME/.discourse_theme, в котором хранятся связи между ключами API и сайтами Discourse для каждой темы.
Таким образом, даже если создание темы завершается сбоем, данные, введённые в «мастере», сохраняются в этом файле. Если вы попытаетесь создать новую тему с тем же именем, URL и ключи API будут получены из этого файла.

3 лайка

Ещё один момент: при использовании предварительного просмотра темы ссылка на «Руководство по стилю» работает некорректно. Она перенаправляет на страницу со стандартной темой, но если добавить к URL ?preview_theme_id=THEME-ID-NUMBER, то «Руководство по стилю» отобразится с правильной темой.

1 лайк

Спасибо, это потрясающе

2 лайка

Здравствуйте, я только начинаю читать пост…
Но прежде чем двигаться дальше, я хотел бы узнать, можно ли использовать CLI с самостоятельно размещённым экземпляром?
Или же нам необходимо использовать CLI с theme-creator.io для разработки, а после завершения «импортировать» тему в самостоятельно размещённый экземпляр?
В моём случае меня больше интересует использование в качестве темы для настройки разового форума, а не создание многоразовой темы, предназначенной для публикации.
Так что мне всё ещё следует использовать CLI с этим публичным сайтом?
Спасибо.

1 лайк

Это возможно, и я рекомендую именно этот метод. Единственное, о чём стоит помнить: все изменения будут сразу же отображаться на форуме по мере их внесения.

Что я делаю: делаю тему выбираемой пользователем, устанавливаю её в личных настройках своего аккаунта, оставляя тему по умолчанию для всех остальных пользователей. Это позволяет видеть любые проблемы, возникающие при настройке темы, только вам.

2 лайка

Я часто делаю это с помощью «тестового» живого сервера, доменное имя которого я не решаюсь прекратить арендовать.

Это более экономично, потому что я просто выключаю сервер на недели, когда не использую его.

Очевидно, я все еще плачу за хранилище (и, возможно, за IP-адрес), но по крайней мере я не плачу за круглосуточные вычислительные ресурсы.

Кажется, есть ещё одно место, которое требует обновления!

1 лайк