Добавьте настройки в тему 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 не распознает их корректно.

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

whitelisted_fruits:
  default: apples|oranges
  type: list

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

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

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

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

Пример реального использования настроек списка можно найти здесь: 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

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

:arrow_up_down: Атрибуты 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 лайка