테마 설정용 Objects 유형

새로운 type: objects테마 설정에 지원되는 유형에 도입합니다. 이 유형은 곧 비추천(deprecate)할 예정인 기존 json_schema 유형을 대체하는 데 사용할 수 있습니다.

objects 유형 테마 설정 정의

objects 유형 테마 설정을 만들려면 먼저 설정 이름으로 사용될 최상위 키를 다른 테마 설정과 동일하게 정의합니다.

links: ...

이어서 설정에 type, default, schema 키워드를 추가합니다.

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

type: objects는 이 설정이 objects 유형임을 나타내며, default: [] 주석은 설정의 기본값을 빈 배열로 설정합니다. schema가 정의된 후에도 기본값을 객체 배열로 설정할 수 있음을 참고하세요. 이 부분은 나중에 시연하겠습니다.

스키마를 정의하려면 먼저 다음과 같이 스키마의 name을 정의합니다:

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

다음으로, 스키마에 properties 키워드를 추가하여 각 객체가 어떤 형태여야 하는지 정의하고 검증할 수 있게 합니다.

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

위 예제에서는 link 객체에 name 속성이 있음을 명시하고 있습니다. 예상되는 데이터 유형을 정의하려면 각 속성에 type 키워드를 정의해야 합니다.

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

위 스키마 정의는 link 객체에 string 유형의 name 속성이 있음을 나타내며, 이는 해당 속성에 문자열 값만 허용됨을 의미합니다. 현재 지원되는 유형은 다음과 같습니다:

  • string: 속성 값이 문자열로 저장됩니다.
  • integer: 속성 값이 정수로 저장됩니다.
  • float: 속성 값이 부동소수점으로 저장됩니다.
  • boolean: 속성 값이 true 또는 false입니다.
  • 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: 속성 값이 유효한 태그 이름 배열입니다.
  • icon: 속성 값은 Discourse 아이콘 세트의 단일 아이콘 이름입니다. 선택된 아이콘은 자동으로 스프라이트 시트에 추가되므로 별도로 등록하지 않고도 렌더링할 수 있습니다.

스키마가 정의된 이제 설정의 기본값을 다음과 같이 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: 속성의 최대 값. 키워드 값은 정수여야 합니다.

tags, groups, categories 유형의 검증

  • min: 속성의 최소 레코드 수. 키워드 값은 정수여야 합니다.
  • max: 속성의 최대 레코드 수. 키워드 값은 정수여야 합니다.

그룹 멤버십 해결

Object 설정은 현재 사용자를 위해 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인 객체 스키마 속성에서만 유효합니다. 중첩된 객체 스키마 및 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 로케일에서 설정에 설명을 추가하려면, 다음과 같은 objects 유형 테마 설정이 주어졌을 때, 다음 형식의 locales/en.yml 파일을 생성합니다.

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: This is a description for the sections theme setting
        schema:
          properties:
            name:
              label: Name
              description: The description for the property
            links:
              name:
                label: Name
                description: The description for the property
              url:
                label: URL
                description: The description for the property

이 문서는 버전 관리됩니다 - github에서 변경 사항을 제안하세요.

16개의 좋아요

I remain to be convinced deprecation of the json schema style is a good idea.

Whilst these can get pretty complex and aren’t the most “developer friendly” of formats (so this is a great change in that regard), there are online tools to validate json schemas which is a really useful way to validate both the schema and against any default data.

e.g. https://www.jsonschemavalidator.net/

How will that work in this new world?

2개의 좋아요

When uploading a theme, we will be validating the default data against the defined schema. That being said, we are not validating that the schema definition is valid now but it wouldn’t be hard for us to do so. Even for the json schema setting right now, I don’t think we are validating the default data against the defined schema.

Our current implementation of json schema type settings is kind of broken in many ways with the most obvious being the editor in the admin interface. We discussed this internally and decided that it is much easier for us to maintain a limited schema format defined by us instead of allowing all the possibilities that comes along with json schema.

2개의 좋아요

Some cool features here:

  • you can get rid of JSON.parse and access the setting directly to the get object which is really nice.

  • the url validator!

:chefs_kiss: :chefs_kiss:

5개의 좋아요

Is there any way for multiple lines to be respected in the editor?

This default works:

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

But once you edit this, the carriage returns are lost

Moreover, it would be nice to have a “text” type that could store more long-form data and perhaps expose a larger “text-area” editor

5개의 좋아요

Here are some feedbacks:

2개의 좋아요

I noticed this and it has been fixed in

https://github.com/discourse/discourse/commit/25bcee43c60c7b707a07934984563e565d04d242

1개의 좋아요

Will we be able to re-order items on the interface?

E.g. that’s the object settings editor on the easy footer theme component. I can’t re-arrange any items right now:

4개의 좋아요

I wanted to request this feature as well! :+1:


On a side note, it would be helpful if the first post contained information about the identifier property.

Before looking at Nolo’s image above, I thought replacing the default child label with a property value was impossible. After looking at the code, I found the identifier property.

4개의 좋아요

Reordering is certainly something that has been brought up internally as well. I’ll try to land that this week.

Noted. I’ll update the first post about the identifier property.

5개의 좋아요

Yep to replace the (soon to be legacy?) json system it needs to match or exceed the old interface:

including the ordering.

1개의 좋아요

Hi, are there any plans to support other field types soon?

For example;

  • a long_string with markdown format; perhaps with customizable toolbar,
  • a date field (with validation rules),
  • a color field (with validation rules)?
1개의 좋아요

There’s no current plan, though I agree that it would be useful. I’d like an icon field myself.

8개의 좋아요

In my experience, it seems to be working like saved presets. In this example the first 2 entries could benefit from these presets, but anything after that all new entries will come up blank initially.

This also means we cannot set default values for each field. for example, if I want to have a checkbox, to start at checked state I cannot have it.

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 will not work in there as expected.

Could there be a way to set the default values per field, for each entries that are created?

Is there a way to import object properties to variables in Sass?

You can always parse the string, but that doesn’t sound like a great idea to promote this way. :sweat_smile:

1개의 좋아요

Thank you for sharing the example! Though yeah.. it doesn’t look that tempting :upside_down_face:

1개의 좋아요

Out of interest, without spending too much time looking, where are we with this?

2개의 좋아요

Yes, it isn’t very good, don’t do it. :smile:. It was more of an attempt to see if it was possible, but not a reasonable approach.
I agree with you; it would be nice to have a direct way! :+1:

I would like to know, too!
Also, if I’m right, that would be the only missing feature parity with the json_schema.

2개의 좋아요

I was looking for the upload type to be available, but it’s not.
A quick look at the core shows that the topic, post, and upload types have been implemented server-side but not in the front end. Is there a specific reason for that? :thinking: