Tipo de objetos para la configuración del tema

Introducimos un nuevo type: objects a los tipos admitidos para configuraciones de tema, el cual puede usarse para reemplazar el tipo existente json_schema, que tenemos la intención de obsoletizar pronto.

Definiendo 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, la cual será usada como el 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 puede establecerse 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 cual nos permitirá definir y validar cómo debería 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 necesita 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 tipo string para la propiedad. Actualmente, se admiten los siguientes tipos:

  • string: El valor de la propiedad se almacena como un string.
  • integer: El valor de la propiedad se almacena como un entero.
  • float: El valor de la propiedad se almacena como un float.
  • boolean: El valor de la propiedad es true o false.
  • upload: El valor de la propiedad es la URL del archivo 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 etiqueta válidos.

Con el esquema definido, el valor predeterminado de la configuración ahora puede establecerse 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 anotando la propiedad 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 propiedad, hay soporte integrado para validaciones personalizadas, las cuales 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 pertenencia a grupo

Las configuraciones de objetos pueden resolver propiedades de 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 está en 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 usuario de administrador y el valor de configuración almacenado aún usan el array original 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 está en al menos uno de los grupos seleccionados para esta sección.
  }
}

Esta opción solo es válida en propiedades de esquema de objeto con type: groups. También funciona en 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 de 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 de configuración y localización

Para añadir una descripción para la configuración en el locale 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: Esta es una descripción para la configuración de tema sections
        schema:
          properties:
            name:
              label: Nombre
              description: La descripción para la propiedad
            links:
              name:
                label: Nombre
                description: La descripción para la propiedad
              url:
                label: URL
                description: La descripción para la propiedad

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: