Tipo de objeto para la configuración del tema

Estamos introduciendo un nuevo type: objects en los tipos admitidos para la configuración de temas, que puede utilizarse para reemplazar el tipo json_schema existente, que se tiene la intención de deprecar pronto.

Definición de una configuración de tema de tipo objects

Para crear una configuración de tema de tipo objects, primero define una clave de nivel superior, igual que cualquier otra configuración de tema, que se utilizará como nombre de la configuración.

links: ...

A continuación, añade las palabras clave type, default y schema a la configuración.

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

type: objects indica que esta será una configuración de tipo objects, mientras que la anotación default: [] establece el valor predeterminado de la configuración como un array vacío. Ten en cuenta que el valor predeterminado también se puede establecer como un array de objetos, lo cual demostraremos una vez que se haya definido el schema.

Para definir el esquema, primero define el name del esquema de la siguiente manera:

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

A continuación, añadiremos la palabra clave properties al esquema, lo que nos permitirá definir y validar cómo debe verse cada objeto.

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

En el ejemplo anterior, estamos indicando que el objeto link tiene una propiedad name. Para definir el tipo de datos esperado, cada propiedad debe definir la palabra clave type.

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

La definición de esquema anterior establece que el objeto link tiene una propiedad name de tipo string, lo que significa que solo se aceptarán valores de cadena para la propiedad. Actualmente, se admiten los siguientes tipos:

  • string: El valor de la propiedad se almacena como una cadena.
  • integer: El valor de la propiedad se almacena como un entero.
  • float: El valor de la propiedad se almacena como un número de punto flotante.
  • boolean: El valor de la propiedad es true o false.
  • upload: El valor de la propiedad es la URL del adjunto
  • enum: El valor de la propiedad debe ser uno de los valores definidos en la palabra clave choices.
    links:
      type: objects
      default: []
      schema:
        name: link
        properties:
          name:
            type: enum
            choices:
              - name 1
              - name 2
              - name 3
    
  • categories: El valor de la propiedad es un array de ids de categoría válidos.
  • groups: El valor de la propiedad es un array de ids de grupo válidos.
  • tags: El valor de la propiedad es un array de nombres de etiquetas válidos.
  • icon: El valor de la propiedad es el nombre de un icono individual del conjunto de iconos de Discourse. Los iconos seleccionados se añaden automáticamente a la hoja de sprites, por lo que pueden renderizarse sin necesidad de registrarse por separado.

Con el esquema definido, ahora se puede establecer el valor predeterminado de la configuración definiendo un array en yaml de la siguiente manera:

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

Propiedades requeridas

Todas las propiedades definidas son opcionales por defecto. Para marcar una propiedad como requerida, simplemente anota la propiedad con required: true. Una propiedad también puede marcarse como opcional anotándola con required: false.

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

Validaciones personalizadas

Para ciertos tipos de propiedades, hay soporte integrado para validaciones personalizadas que pueden declararse anotando la propiedad con la palabra clave validations.

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

Validaciones para tipos string

  • min_length: Longitud mínima de la propiedad. El valor de la palabra clave debe ser un entero.
  • max_length: Longitud máxima de la propiedad. El valor de la palabra clave debe ser un entero.
  • url: Valida que la propiedad sea una URL válida. El valor de la palabra clave puede ser true/false.

Validaciones para tipos integer y float

  • min: Valor mínimo de la propiedad. El valor de la palabra clave debe ser un entero.
  • max: Valor máximo de la propiedad. El valor de la palabra clave debe ser un entero.

Validaciones para tipos tags, groups y categories

  • min: Número mínimo de registros para la propiedad. El valor de la palabra clave debe ser un entero.
  • max: Número máximo de registros para la propiedad. El valor de la palabra clave debe ser un entero.

Resolución de la pertenencia a grupos

Las configuraciones de objetos pueden resolver las propiedades type: groups a un booleano para el usuario actual. Esto es útil cuando el código del tema solo necesita saber si el usuario actual pertenece a uno de los grupos configurados, porque currentUser.groups solo incluye grupos que son visibles para el usuario.

Añade resolve_group_membership: true a la propiedad 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

La interfaz de administración y el valor de configuración almacenado siguen utilizando el array original de groups. En el objeto settings de tiempo de ejecución del frontend, Discourse elimina los ids de grupo de cada objeto y añade un booleano con el mismo nombre de propiedad prefijado por user_in_:

for (const section of settings.menu_sections) {
  if (section.user_in_groups) {
    // El usuario pertenece al menos a un grupo seleccionado para esta sección.
  }
}

Esta opción solo es válida para propiedades del esquema de objetos con type: groups. También funciona con esquemas de objetos anidados y con grupos automáticos como logged_in_users y anonymous_users.

Estructura de objetos anidados

Un objeto también puede tener una propiedad que contenga un array de objetos. Para crear una estructura de objetos anidados, una propiedad también puede anotarse con type: objects y la definición schema asociada.

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

Descripción y localización de la configuración

Para añadir una descripción para la configuración en la localización en, crea un archivo locales/en.yml con el siguiente formato, dada la siguiente configuración de tema de tipo 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

Este documento está bajo control de versiones - sugiere cambios en github.

16 Me gusta

Aún no me han convencido de que la eliminación del estilo de esquema JSON sea una buena idea.

Si bien estos pueden volverse bastante complejos y no son los formatos más “amigables para el desarrollador” (por lo que este es un gran cambio en ese sentido), existen herramientas en línea para validar esquemas JSON, lo cual es una forma realmente útil de validar tanto el esquema como contra cualquier dato predeterminado.

por ejemplo: https://www.jsonschemavalidator.net/

¿Cómo funcionará eso en este nuevo mundo?

2 Me gusta

Al cargar un tema, validaremos los datos predeterminados contra el esquema definido. Dicho esto, no estamos validando que la definición del esquema sea válida ahora, pero no nos sería difícil hacerlo. Incluso para la configuración del esquema json en este momento, no creo que estemos validando los datos predeterminados contra el esquema definido.

Nuestra implementación actual de la configuración del tipo de esquema json está algo rota de muchas maneras, siendo la más obvia el editor en la interfaz de administración. Discutimos esto internamente y decidimos que es mucho más fácil para nosotros mantener un formato de esquema limitado definido por nosotros en lugar de permitir todas las posibilidades que vienen con el esquema json.

2 Me gusta

Aquí hay algunas características geniales:

  • puedes deshacerte de JSON.parse y acceder a la configuración directamente para obtener el objeto, lo cual es realmente bueno.

  • ¡el validador de URL!

:chefs_kiss: :chefs_kiss:

5 Me gusta

¿Hay alguna forma de respetar varias líneas en el editor?

Esto por defecto funciona:

- name: markdown
  value: > 
    ## Encabezado
      * primer punto
      * segundo punto

Pero una vez que editas esto, los saltos de línea se pierden

Además, sería bueno tener un tipo “texto” que pudiera almacenar datos de formato más largo y quizás exponer un editor de “área de texto” más grande.

5 Me gusta

Aquí hay algunos comentarios:

2 Me gusta

Me di cuenta de esto y se ha corregido en

1 me gusta

¿Podremos reordenar elementos en la interfaz?

Por ejemplo, este es el editor de configuración de objetos en el componente de tema de pie de página fácil. No puedo reorganizar ningún elemento en este momento:

4 Me gusta

¡Quería solicitar esta función también! :+1:


Por cierto, sería útil si la primera publicación contuviera información sobre la propiedad identifier.

Antes de ver la imagen de Nolo de arriba, pensé que reemplazar la etiqueta de hijo predeterminada con un valor de propiedad era imposible. Después de ver el código, encontré la propiedad identifier.

4 Me gusta

La reordenación es algo que también se ha planteado internamente. Intentaré implementarla esta semana.

Tomado nota. Actualizaré la primera publicación sobre la propiedad identifier.

5 Me gusta

Sí, para reemplazar el sistema JSON (que pronto será obsoleto?) necesita igualar o superar la interfaz antigua:

incluyendo el orden.

1 me gusta

Hola, ¿hay planes para admitir otros tipos de campos pronto?

Por ejemplo;

  • una long_string con formato markdown; quizás con una barra de herramientas personalizable,
  • un campo date (con reglas de validación),
  • un campo color (con reglas de validación)?
1 me gusta

No hay planes actuales, aunque estoy de acuerdo en que sería útil. Yo mismo querría un campo icon.

8 Me gusta

En mi experiencia, parece que funciona como ajustes preestablecidos guardados. En este ejemplo, las primeras 2 entradas podrían beneficiarse de estos ajustes preestablecidos, pero cualquier cosa después de eso, todas las nuevas entradas aparecerán en blanco inicialmente.

Esto también significa que no podemos establecer valores predeterminados para cada campo. Por ejemplo, si quiero que una casilla de verificación comience marcada, no puedo hacerlo.

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 no funcionará allí como se esperaba.

¿Podría haber una manera de establecer los valores predeterminados por campo, para cada una de las entradas que se crean?

¿Hay alguna forma de importar propiedades de objetos a variables en Sass?

Siempre puedes analizar la cadena, pero no parece una buena idea promocionarlo de esta manera. :sweat_smile:

1 me gusta

¡Gracias por compartir el ejemplo! Aunque sí… no parece muy tentador :upside_down_face:

1 me gusta

Por cierto, sin dedicar demasiado tiempo a buscar, ¿cómo vamos con esto?

2 Me gusta

Sí, no es muy bueno, no lo hagas. :smile:. Fue más un intento de ver si era posible, pero no un enfoque razonable.
Estoy de acuerdo contigo; ¡sería bueno tener una forma directa! :+1:

¡Me gustaría saberlo también!
Además, si no me equivoco, esa sería la única característica que faltaría para la paridad con el json_schema.

2 Me gusta

Estaba buscando que el tipo de carga estuviera disponible, pero no lo está. Un vistazo rápido al núcleo muestra que los tipos de tema, publicación y carga se han implementado en el lado del servidor pero no en el front-end. ¿Hay alguna razón específica para eso? :thinking: