为您的 Discourse 主题添加设置

Discourse 允许主题拥有“设置”,主题开发者可以添加这些设置,使站点所有者能够通过 UI 自定义主题,而无需更改任何代码行,也无需担心在主题未来的更新中丢失他们的更改。

主题还可以更改某些可主题化的站点设置,有关此内容的更多信息,请参阅 可主题化站点设置 主题。

:heavy_plus_sign: 向您的主题添加设置

向主题添加设置与添加 CSS 和 JS 代码略有不同,即无法通过 UI 进行此操作。

添加设置的方法是创建一个 主题仓库,并在仓库的根文件夹中创建一个新的 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

话虽如此,在处理 listenum 设置时,您 需要 设置类型属性,否则 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

现在您就支持了 3 种语言:英语、阿拉伯语和法语。

额外的设置属性和选项

最小值和最大值属性

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

要指定限制,只需向设置添加 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

: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 个赞