为你的 Discourse 主题添加设置

Discourse 允许主题为站点所有者提供“设置”功能。主题开发者可以添加这些设置,使站点所有者能够通过用户界面(UI)自定义主题,而无需修改任何代码,也不必担心在主题的未来更新中丢失所做的更改。

主题还可以修改某些可主题化的站点设置。有关该功能的更多信息,请参阅可主题化站点设置主题。

: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. objectsjson_schema 的替代方案)
  8. upload(用于图像)
  9. icon(用于 Discourse 图标集中的单个图标)

您可以通过向设置添加 type 属性来指定类型,例如:

float_setting:
  type: float
  default: 3.14

我应该指出,您并不总是需要显式设置 type 属性,因为 Discourse 足够智能,可以根据设置的默认值推断出设置类型。因此,您可以将上述示例简化为:

float_setting:
  default: 3.14

话虽如此,当处理 listenumicon 设置时,您_必须_设置 type 属性,否则 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 会将所选图标添加到 sprite sheet 中,因此您可以在主题中渲染它,而无需单独注册。

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 属性

有时您可能需要指定设置值不能超过的限制,以防止您的用户意外破坏主题,甚至可能是整个站点。

要指定限制,只需向您的设置添加 minmax 或两者属性,如下所示:

integer_setting:
  default: 10
  min: 5
  max: 100

您可以为 integerfloatstring 类型的设置指定限制。对于 integerfloat 设置,设置本身的值将与限制进行比较。而对于 string 设置,值的长度将与指定的限制进行比较。

如果用户尝试输入不在允许范围内的值,他们将看到一个错误,告知他们最小值和最大值是多少。

在您的 JS/CSS/Handlebars 中访问设置

主题设置在主题 JavaScript 文件中作为全局 settings 变量提供。例如:

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

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

这个 settings 对象也可以在 .gjs <template> 标签中正常用作普通变量。

设置 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: listlist_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_usersanonymous_users。对象主题设置可以在 type: groups 属性上使用相同的选项。有关详细信息,请参阅主题设置的 objects 类型

:link: 相关主题


本文档受版本控制 - 建议修改 on 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 个赞