Добавьте настройки в тему 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: Поддерживаемые типы

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

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

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

float_setting:
  type: float
  default: 3.14

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

float_setting:
  default: 3.14

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

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

whitelisted_fruits:
  default: apples|oranges
  type: list

Настройка типа Enum:

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

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

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

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

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

Тип 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 для каждой настройки вашей темы будет создана переменная, и каждая переменная будет иметь то же имя, что и настройка, которую она представляет.

Таким образом, если у вас есть настройка с плавающей запятой под названием 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.

: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 лайк