为 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,这是一个字符串设置,默认值为“我的论坛”;以及 max_avatars,这是一个整数设置,默认值为 7。

您可以在 JS 代码中像这样访问您的设置:settings.your_setting_key

到目前为止,我们已经介绍了定义设置的最简单方法。在下一节中,我们将更深入地探讨各种设置类型及其使用方法。

:symbols: 支持的类型

共有 8 种设置类型:

  1. integer
  2. float
  3. string
  4. bool(布尔值)
  5. list
  6. enum
  7. objectsjson_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

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

其他设置属性和选项

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: 相关主题


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