主题设置的 Objects 类型

我们引入了一个新的 type: objects主题设置支持类型中,可用于替换现有的 json_schema 类型,我们计划不久后将其弃用。

定义 objects 类型的主题设置

要创建 objects 类型的主题设置,首先像任何主题设置一样定义一个顶级键,它将用作设置的名称。

links: ...

接下来,向设置中添加 typedefaultschema 关键字。

links:
  type: objects
  default: []
  schema: ...

type: objects 表示这是一个 objects 类型的设置,而 default: [] 注解将设置的默认值设为空数组。请注意,默认值也可以设置为对象数组,我们将在定义 schema 后演示这一点。

要定义 schema,首先像这样定义 schema 的 name

links:
  type: objects
  default: []
  schema:
    name: link

接下来,我们将向 schema 添加 properties 关键字,这将允许我们定义和验证每个对象的结构。

links:
  type: objects
  default: []
  schema:
    name: link
    properties:
      name: ...

在上面的示例中,我们声明 link 对象有一个 name 属性。为了定义预期的数据类型,每个属性都需要定义 type 关键字。

links:
  type: objects
  default: []
  schema:
    name: link
    properties:
      name:
        type: string

上述 schema 定义声明 link 对象有一个类型为 stringname 属性,这意味着该属性仅接受字符串值。目前支持以下类型:

  • string:属性值存储为字符串。
  • integer:属性值存储为整数。
  • float:属性值存储为浮点数。
  • boolean:属性值为 truefalse
  • upload:属性值为附件 URL。
  • enum:属性值必须是 choices 关键字中定义的值之一。
    links:
      type: objects
      default: []
      schema:
        name: link
        properties:
          name:
            type: enum
            choices:
              - name 1
              - name 2
              - name 3
    
  • categories:属性值为有效分类 ID 数组。
  • groups:属性值为有效群组 ID 数组。
  • tags:属性值为有效标签名称数组。

定义 schema 后,现在可以通过在 yaml 中定义数组来设置设置的默认值,如下所示:

links:
  type: objects
  default:
    - name: link 1
      title: link 1 title
    - name: link 2
      title: link 2 title
  schema:
    name: link
    properties:
      name:
        type: string
      title:
        type: string

必填属性

默认情况下,所有定义的属性都是可选的。要将属性标记为必填,只需使用 required: true 注解该属性。也可以使用 required: false 注解将属性标记为可选。

links:
  type: objects
  default: []
  schema:
    name: link
    properties:
      name:
        type: string
        required: true
      title:
        type: string
        required: false

自定义验证

对于某些属性类型,内置支持自定义验证,可以通过使用 validations 关键字注解属性来声明。

links:
  type: objects
  default: []
  schema:
    name: link
    properties:
      name:
        type: string
        required: true
        validations:
          min: 1
          max: 2048
          url: true

string 类型的验证

  • min_length:属性的最小长度。关键字的值必须是整数。
  • max_length:属性的最大长度。关键字的值必须是整数。
  • url:验证属性是否为有效的 URL。关键字的值可以是 true/false

integerfloat 类型的验证

  • min:属性的最小值。关键字的值必须是整数。
  • max:属性的最大值。关键字的值必须是整数。

tagsgroupscategories 类型的验证

  • min:属性的最小记录数。关键字的值必须是整数。
  • max:属性的最大记录数。关键字的值必须是整数。

解析群组成员身份

对象设置可以将 type: groups 属性解析为当前用户的布尔值。当主题代码只需要知道当前用户是否在配置的群组之一中时,这非常有用,因为 currentUser.groups 仅包含对用户可见的群组。

groups 属性添加 resolve_group_membership: true

menu_sections:
  type: objects
  default:
    - name: section 1
      groups:
        - 1
        - 3
  schema:
    name: menu section
    properties:
      name:
        type: string
      groups:
        type: groups
        resolve_group_membership: true

管理 UI 和存储的设置值仍使用原始的 groups 数组。在前端运行时 settings 对象中,Discourse 会从每个对象中移除群组 ID,并添加一个以 user_in_ 为前缀的同名布尔值:

for (const section of settings.menu_sections) {
  if (section.user_in_groups) {
    // 用户在该部分的至少一个选定群组中。
  }
}

此选项仅对具有 type: groups 的对象 schema 属性有效。它也适用于嵌套对象 schema 以及自动群组,如 logged_in_usersanonymous_users

嵌套对象结构

对象也可以包含一个由对象组成的数组作为属性。为了创建嵌套对象结构,属性也可以使用 type: objects 和相关的 schema 定义进行注解。

sections:
  type: objects
  default:
    - name: section 1
      links:
        - name: link 1
          url: /some/url
        - name: link 2
          url: /some/other/url
  schema:
    name: section
    properties:
      name:
        type: string
        required: true
      links:
        type: objects
        schema:
          name: link
          properties:
            name:
              type: string
            url:
              type: string

设置描述和本地化

要为 en 语言环境中的设置添加描述,请创建一个文件 locales/en.yml,格式如下,针对以下 objects 类型的主题设置。

sections:
  type: objects
  default:
    - name: section 1
      links:
        - name: link 1
          url: /some/url
        - name: link 2
          url: /some/other/url
  schema:
    name: section
    properties:
      name:
        type: string
        required: true
      links:
        type: objects
        schema:
          name: link
          properties:
            name:
              type: string
            url:
              type: string
en:
  theme_metadata:
    settings:
      sections:
        description: 这是 sections 主题设置的描述
        schema:
          properties:
            name:
              label: 名称
              description: 属性的描述
            links:
              name:
                label: 名称
                description: 属性的描述
              url:
                label: URL
                description: 属性的描述

本文档受版本控制 - 在 github 上建议更改。

16 个赞

我仍然不相信弃用 json schema 风格是个好主意。

虽然这些可能变得相当复杂,而且不是最“开发者友好”的格式(所以在这方面这是一个巨大的改变),但有在线工具可以验证 json schema,这是一种非常有用的方式来验证 schema 本身以及针对任何默认数据。

例如 https://www.jsonschemavalidator.net/

在这个新世界里,那将如何运作?

2 个赞

上传主题时,我们将根据定义的模式验证默认数据。话虽如此,我们现在不验证模式定义是否有效,但要做到这一点并不难。即使是现在的 json 模式设置,我认为我们也没有根据定义的模式验证默认数据。

我们目前 json 模式类型设置的实现方式在很多方面都有些问题,最明显的是管理界面中的编辑器。我们内部讨论过,并决定我们维护一个由我们定义的有限模式格式比允许 json 模式带来的所有可能性要容易得多。

2 个赞

这里有一些很酷的功能:

  • 您可以摆脱 JSON.parse 并直接访问设置以获取对象,这真的很棒。

  • URL 验证器!

:chefs_kiss: :chefs_kiss:

5 个赞

编辑器是否可以保留多行?

默认 可以

- name: markdown
  value: > 
    ## Heading
      * first bullet
      * second bullet

但一旦你编辑了它,回车符就会丢失

此外,最好有一个“text”类型,可以存储更长格式的数据,并可能暴露一个更大的“textarea”编辑器。

5 个赞

以下是一些反馈:

2 个赞

我注意到了这一点,它已在以下位置修复:

1 个赞

我们能否在界面上重新排序项目?

例如,这是 easy footer 主题组件上的对象设置编辑器。我现在无法重新排列任何项目:

4 个赞

我也想请求此功能!:+1:


另外,首帖包含有关 identifier 属性的信息会很有帮助。

在查看上面 Nolo 的图片之前,我认为无法用属性值替换默认的子标签。查看代码后,我找到了 identifier 属性。

4 个赞

重新排序当然是我们内部也提出过的一个功能。我本周会尝试实现它。

知道了。我将更新首帖关于 identifier 属性的信息。

5 个赞

是的,要替换(即将成为遗留的?)json 系统,它需要匹配或超过旧接口:

包括排序。

1 个赞

您好,有计划很快支持其他字段类型吗?

例如:

  • 支持 markdown 格式的 long_string;也许带有可自定义的工具栏,
  • date 字段(带验证规则),
  • color 字段(带验证规则)?
1 个赞

目前还没有计划,尽管我同意这会很有用。我个人想要一个 icon 字段。

8 个赞

根据我的经验,这似乎就像保存的预设一样工作。在此示例中,前 2 个条目可以受益于这些预设,但之后的所有新条目最初都会显示为空白。

这意味着我们也无法为每个字段设置默认值。例如,如果我希望一个复选框一开始就处于选中状态,这是无法实现的。

links:
  type: objects
  default:
    - name: link 1
      title: link 1 title
    - name: link 2
      title: link 2 title
  schema:
    name: link
    properties:
      is_active:
        type: boolean
        default: true

default: true 在那里无法按预期工作。

是否有办法为每个创建的条目设置每个字段的默认值?

在 Sass 中有办法将对象属性导入变量吗?

你可以随时解析字符串,但这听起来不是一个好主意。:sweat_smile:

1 个赞

谢谢分享示例!不过是的……它看起来并不那么诱人 :upside_down_face:

1 个赞

顺便问一下,不用花太多时间看,我们在这方面进展如何?

2 个赞

是的,这不太好,不要这样做。 :smile: 这更多是尝试看看是否可行,而不是一个合理的方法。
我同意你;有一个直接的方法会很好! :+1:

我也想知道!
另外,如果我没记错的话,这将是与 json_schema 唯一缺失的功能奇偶校验。

2 个赞

我一直在寻找上传类型可用,但它不可用。
快速查看核心,发现主题、帖子和上传类型已在服务器端实现,但未在前台实现。有什么特别的原因吗?:thinking: