Тип объектов для настройки темы

Мы представляем новый type: objects для поддерживаемых типов настроек тем, который можно использовать для замены существующего типа 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
```\n
Далее мы добавим ключевое слово `properties` к схеме, которое позволит нам определить и проверить, как должен выглядеть каждый объект.

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

В приведенном выше примере мы указываем, что объект link имеет свойство name. Чтобы определить тип ожидаемых данных, каждое свойство должно определять ключевое слово type.

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

Приведенное выше определение схемы указывает, что объект link имеет свойство name типа string, что означает, что для свойства будут приниматься только строковые значения. В настоящее время поддерживаются следующие типы:

  • 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: Значение свойства — это массив действительных идентификаторов категорий.
  • groups: Значение свойства — это массив действительных идентификаторов групп.
  • tags: Значение свойства — это массив действительных имен тегов.

После определения схемы значение настройки по умолчанию теперь можно установить, определив массив в 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.

Валидация для типов integer и float

  • min: Минимальное значение свойства. Значение ключевого слова должно быть целым числом.
  • max: Максимальное значение свойства. Значение ключевого слова должно быть целым числом.

Валидация для типов tags, groups и categories

  • min: Минимальное количество записей для свойства. Значение ключевого слова должно быть целым числом.
  • max: Максимальное количество записей для свойства. Значение ключевого слова должно быть целым числом.

Определение членства в группе

Настройки объектов могут преобразовывать свойства type: groups в логическое значение для текущего пользователя. Это полезно, когда коду темы нужно только знать, находится ли текущий пользователь в одной из настроенных групп, потому что currentUser.groups включает только группы, видимые пользователю.

Добавьте resolve_group_membership: true к свойству groups:

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

Интерфейс администратора и хранимое значение настройки по-прежнему используют исходный массив groups. В объекте settings во время выполнения на стороне клиента Discourse удаляет идентификаторы групп из каждого объекта и добавляет логическое значение с тем же именем свойства с префиксом user_in_:

for (const section of settings.menu_sections) {
  if (section.user_in_groups) {
    // User is in at least one selected group for this section.
  }
}

Этот параметр действителен только для свойств схемы объектов с type: groups. Он также работает со вложенными схемами объектов и с автоматическими группами, такими как logged_in_users и anonymous_users.

Вложенная структура объектов

n
Объект также может иметь свойство, которое содержит массив объектов. Чтобы создать вложенную структуру объектов, свойство также можно пометить 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: 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 лайков

Мне всё ещё не очевидно, что отказ от стиля JSON Schema — это хорошая идея.

Хотя эти схемы могут становиться довольно сложными и не являются самым «дружелюбным к разработчикам» форматом (так что в этом плане это отличное изменение), существуют онлайн-инструменты для валидации JSON Schema, что является действительно полезным способом проверки как самой схемы, так и любых данных по умолчанию.

Например: https://www.jsonschemavalidator.net/

Как это будет работать в новом мире?

2 лайка

При загрузке темы мы будем проверять данные по умолчанию на соответствие определённой схеме. Тем не менее, в настоящее время мы не проверяем валидность самой схемы, хотя это не составило бы для нас большого труда. Даже для настройки JSON Schema сейчас, я не думаю, что мы проверяем данные по умолчанию на соответствие определённой схеме.

Наша текущая реализация настроек типа JSON Schema во многих отношениях некорректна, и самое очевидное — это редактор в административном интерфейсе. Мы обсудили это внутренне и решили, что нам гораздо проще поддерживать ограниченный формат схемы, определённый нами, чем разрешать все возможности, которые предоставляет JSON Schema.

2 лайка

Здесь есть несколько крутых функций:

  • Вы можете отказаться от JSON.parse и получать доступ к настройке напрямую к объекту get, что очень удобно.

  • Валидатор URL!

:chefs_kiss: :chefs_kiss:

5 лайков

Есть ли способ, чтобы в редакторе учитывались несколько строк?

Это по умолчанию работает:

- name: markdown
  value: > 
    ## Заголовок
      * первый пункт
      * второй пункт

Но как только вы отредактируете это, переносы строк теряются.

Кроме того, было бы неплохо иметь тип «текст», который мог бы хранить более объемные данные и, возможно, предоставлять редактор с большим «текстовым полем».

5 лайков

Вот несколько замечаний:

2 лайка

Я заметил это, и проблема была исправлена в

1 лайк

Будет ли у нас возможность менять порядок элементов в интерфейсе?

Например, это редактор настроек объекта в компоненте темы «Лёгкий подвал». Сейчас я не могу переставить ни один элемент:

4 лайка

Я тоже хотел бы предложить эту функцию! :+1:


Кстати, было бы полезно, если бы в первом сообщении содержалась информация о свойстве identifier.

Прежде чем увидеть изображение Ноло выше, я думал, что замена стандартной метки дочернего элемента значением свойства невозможна. Изучив код, я обнаружил свойство identifier.

4 лайка

Изменение порядка элементов определённо также обсуждалось внутри команды. Я постараюсь внедрить это на этой неделе.

Принято. Я обновлю первое сообщение, добавив информацию о свойстве identifier.

5 лайков

Да, чтобы заменить (скоро устаревающую?) систему JSON, она должна соответствовать или превосходить старый интерфейс:

включая порядок элементов.

1 лайк

Привет! Планируется ли в ближайшее время поддержка других типов полей?

Например:

  • long_string с форматированием Markdown; возможно, с настраиваемой панелью инструментов,
  • поле date (с правилами валидации),
  • поле color (с правилами валидации)?
1 лайк

В настоящее время таких планов нет, хотя я согласен, что это было бы полезно. Мне самому хотелось бы иметь поле icon.

8 лайков

По моему опыту, это работает как сохранённые предустановки. В данном примере первые два элемента могли бы выиграть от таких предустановок, но все последующие новые элементы будут изначально пустыми.

Это также означает, что мы не можем задать значения по умолчанию для каждого поля. Например, если я хочу, чтобы флажок изначально был установлен, это невозможно.

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: