Добавление настроек в тему Discourse

Discourse позволяет темам иметь «настройки», которые разработчики тем могут добавлять, чтобы владельцы сайтов могли настраивать темы через интерфейс, не изменяя ни одной строки кода и не беспокоясь о потере изменений при будущих обновлениях темы.

Темы также могут изменять определенные настраиваемые параметры сайта. Для получения дополнительной информации см. тему Настраиваемые параметры сайта.

:heavy_plus_sign: Добавление настроек в вашу тему

Добавление настроек в тему немного отличается от добавления кода CSS и JS: это невозможно сделать через интерфейс.

Способ добавить настройки — создать репозиторий для вашей темы и в корневой папке вашего репозитория создать новый файл settings.yaml (или settings.yml). В этом файле вы будете использовать язык YAML для определения настроек вашей темы.

:loudspeaker: Примечание: Вам может пригодиться использование Theme CLI, которое значительно упрощает процесс разработки.

Если вы знакомы с разработкой плагинов, это не будет для вас новостью — в основном это работает так же, как добавление параметров сайта в ваш плагин. Просто добавьте валидный YAML в файл настроек, и всё будет готово.

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

simple_setting: true

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

Аналогичным образом, вы можете добавить что-то вроде этого:

site_name: My Forums
max_avatars: 7

И у вас появится две дополнительные настройки: site_name, которая будет строковой настройкой со значением по умолчанию “My Forums”, и max_avatars как целочисленная настройка со значением по умолчанию 7.

Вы можете обращаться к своим настройкам в JS-коде так: settings.your_setting_key.

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

:symbols: Поддерживаемые типы

Существует 9 типов настроек:

  1. integer
  2. float
  3. string
  4. bool (для логических значений)
  5. list
  6. enum
  7. objects (замена для json_schema)
  8. upload (для изображений)
  9. icon (для одной иконки из набора иконок Discourse)

И вы можете указать тип, добавив атрибут type к вашей настройке, как здесь:

float_setting:
  type: float
  default: 3.14

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

float_setting:
  default: 3.14

Тем не менее, вы должны установить атрибут типа при работе с настройками list, enum и icon, иначе Discourse не распознает их правильно.

Настройка списка (List Setting):

whitelisted_fruits:
  default: apples|oranges
  type: list

Настройка перечисления (Enum Setting):

favorite_fruit:
  default: orange
  type: enum
  choices:
    - apple
    - banana

Если разница между настройками списка и перечисления вам не ясна: настройки перечисления позволяют пользователям вашей темы выбирать только одно значение из набора значений, определенных вами (см. атрибут choices).

С другой стороны, настройки списка позволяют вашим пользователям создавать собственный список (т.е. массив) значений. Они могут добавлять в список значений по умолчанию настройки или удалять из него.
Вы можете установить список значений по умолчанию для настройки, соединив значения символом вертикальной черты |. См. настройку списка в примере выше.

Вы можете увидеть реальный пример использования настроек списка здесь: Auto-Linkify Words.

:loudspeaker: Примечание: Обращайте внимание на отступы при работе с YAML, так как YAML очень чувствителен к пробелам и выдаст ошибку синтаксиса, если отступы в вашем коде неверны.

Настройка иконки (Icon Setting):

banner_icon:
  default: bullhorn
  type: icon

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

Тип objects

Тип настройки objects — это специальный тип, который позволяет вам создавать продвинутые настройки с настраиваемой структурой и валидациями. Для этого типа есть отдельная документация.

:capital_abcd: Описание настроек и локализация

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

whitelisted_fruits:
  default: apples|oranges
  type: list
  description: "Этот текст будет отображаться под этой настройкой и объяснять, что она делает!"

И вы получите это:

Поддержка нескольких языков

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

Прежде всего, убедитесь, что язык, который вы хотите поддерживать, есть в этом списке:

Список языков
Код Название
ar اللغة العربية
bs_BA bosanski jezik
ca català
cs čeština
da dansk
de Deutsch
el ελληνικά
en English
es Español
et eesti
fa_IR فارسی
fi suomi
fr Français
gl galego
he עברית
id Indonesian
it Italiano
ja 日本語
ko 한국어
lv latviešu valoda
nb_NO Norsk bokmål
nl Nederlands
pl_PL język polski
pt Português
pt_BR Português (BR)
ro limba română
ru Русский
sk slovenčina
sq Shqip
sr српски језик
sv svenska
te తెలుగు
th ไทย
tr_TR Türkçe
uk українська мова
ur اردو
vi Việt Nam
zh_CN 中文
zh_TW 中文 (TW)

(Если вы не видите свой язык в списке, возможно, вам стоит взглянуть на How to add a new language)

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

whitelisted_fruits:
  default: apples|oranges
  type: list
  description:
    en: English text
    ar: نص باللغة العربية
    fr: Texte français

И теперь у вас есть поддержка 3 языков: английского, арабского и французского.

Дополнительные атрибуты и опции настроек

Атрибуты Min и max

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

Чтобы указать ограничения, просто добавьте атрибут min или max или оба к вашей настройке, как здесь:

integer_setting:
  default: 10
  min: 5
  max: 100

Вы можете указать ограничения для настроек типа integer, float и string. Для настроек integer и float само значение настройки проверяется на соответствие ограничениям. А для настроек string длина значения проверяется на соответствие указанным ограничениям.

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

Доступ к настройкам в вашем JS/CSS/Handlebars

Настройки темы доступны глобально как переменная settings в файлах JavaScript темы. Например:

// {theme}/javascripts/discourse/api-initializers/init-theme.gjs
import { apiInitializer } from "discourse/lib/api";

export default apiInitializer((api) => {
  console.log("settings are", settings);
});

Этот объект settings также можно использовать как обычный внутри тегов <template> в .gjs.

Установка CSS-переменных

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

Так что, если у вас была настройка float с именем global_font_size и строковая настройка с именем site_background, вы могли бы сделать что-то вроде этого в CSS вашей темы:

html {
  font-size: #{$global-font-size}px;
  background: $site-background;
}

Разрешение членства в группах

Компонентам темы иногда необходимо показывать или скрывать функцию на основе того, находится ли текущий пользователь в настроенной группе. Избегайте проверки currentUser.groups для этого, так как он включает только группы, видимые пользователю, и может упускать скрытые группы.

Для настроек списка, основанных на группах, добавьте resolve_group_membership: true, чтобы разрешить проверку на стороне сервера:

copy_button_allowed_groups:
  default: "1|3"
  type: list
  list_type: group
  resolve_group_membership: true

Этот вариант действителен только тогда, когда настройка имеет type: list и list_type: group. Когда он включен, объект settings на фронтенде не включает исходный список групп. Вместо этого Discourse добавляет булево значение с тем же именем настройки, но с префиксом user_in_:

// {theme}/javascripts/discourse/api-initializers/init-theme.gjs
import { apiInitializer } from "discourse/lib/api";

export default apiInitializer((api) => {
  if (!settings.user_in_copy_button_allowed_groups) {
    return;
  }

  // Пользователь находится хотя бы в одной выбранной группе.
});

Сгенерированное булево значение также работает с автоматическими группами, такими как logged_in_users и anonymous_users. Настройки объектов темы могут использовать тот же вариант для свойств type: groups. Подробности см. в objects type for theme settings.

:link: Связанные темы


Этот документ управляется по версиям - предложите изменения на github.

54 лайка

Интересно, стоит ли нам заменить этот раздел чем-то, касающимся: Objects type for theme setting

Возможно, нам также стоит добавить ссылку из этой документации на: Migrate Discourse theme settings

5 лайков

Да. Я потратил почти час, пытаясь заставить json_schemas работать. (Хотя я знал о новом и улучшенном способе решения этой задачи!!)

@Osama, если ты не можешь обновить это самостоятельно, пожалуйста, попроси кого-нибудь, кто может. Спасибо.

4 лайка

Извините, что это произошло. Вот PR для обновления документации: Replace references to `json_schema` with `objects` type documentation by OsamaSayegh · Pull Request #26 · discourse/discourse-developer-docs · GitHub

3 лайка

Как я могу использовать изображение, определенное как ресурс, в качестве значения по умолчанию для поля загрузки в настройках темы?

К сожалению, следующий вариант не работает. Интересно, есть ли для этого специальный метод. Или вообще, возможно ли это?

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

// about.json
{
  "assets": {
    "box_default_image": "assets/box-default-image.png"
  }
}
# settings.yml

box_image:
  type: upload
  default: settings.theme_uploads.box_default_image
1 лайк

Вы пробовали ключ из about.json? Что-то вроде

# settings.yml

box_image:
  type: upload
  default: "box_default_image"
1 лайк

@moin Это работает отлично! Спасибо!

1 лайк