Tipo di oggetti per le impostazioni del tema

Stiamo introducendo un nuovo type: objects nei tipi supportati per le impostazioni del tema, che può essere utilizzato per sostituire il tipo json_schema esistente, che intendiamo deprecare presto.

Definizione di un’impostazione del tema di tipo objects

Per creare un’impostazione del tema di tipo objects, definisci prima una chiave di livello superiore, proprio come qualsiasi altra impostazione del tema, che verrà utilizzata come nome dell’impostazione.

links: ...

Aggiungi successivamente le parole chiave type, default e schema all’impostazione.

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

type: objects indica che si tratta di un’impostazione di tipo objects, mentre l’annotazione default: [] imposta il valore predefinito dell’impostazione su un array vuoto. Nota che il valore predefinito può anche essere impostato su un array di oggetti, cosa che dimostreremo una volta definita lo schema.

Per definire lo schema, definisci prima il name dello schema in questo modo:

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

Successivamente, aggiungeremo la parola chiave properties allo schema, che ci permetterà di definire e validare l’aspetto che deve avere ogni oggetto.

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

Nell’esempio sopra, stabiliamo che l’oggetto link ha una proprietà name. Per definire il tipo di dati atteso, ogni proprietà deve definire la parola chiave type.

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

La definizione dello schema sopra indica che l’oggetto link ha una proprietà name di tipo string, il che significa che per la proprietà saranno accettati solo valori stringa. Attualmente sono supportati i seguenti tipi:

  • string: Il valore della proprietà viene salvato come stringa. Imposta textarea: true per utilizzare un’area di testo espandibile:

    description:
      type: string
      textarea: true
      validations:
        max_length: 500
    
  • integer: Il valore della proprietà viene salvato come numero intero.

  • float: Il valore della proprietà viene salvato come numero in virgola mobile.

  • boolean: Il valore della proprietà è true o false.

  • upload: Il valore della proprietà è l’URL dell’allegato.

  • enum: Il valore della proprietà deve essere uno dei valori definiti nella parola chiave choices.

    links:
      type: objects
      default: []
      schema:
        name: link
        properties:
          name:
            type: enum
            choices:
              - name 1
              - name 2
              - name 3
    
  • categories: Il valore della proprietà è un array di ID di categorie validi.

  • groups: Il valore della proprietà è un array di ID di gruppi validi.

  • tags: Il valore della proprietà è un array di nomi di tag validi.

  • icon: Il valore della proprietà è il nome di una singola icona dall’insieme di icone di Discourse. Le icone selezionate vengono aggiunte automaticamente allo sprite sheet, quindi possono essere renderizzate senza essere registrate separatamente.

Una volta definito lo schema, il valore predefinito dell’impostazione può ora essere impostato definendo un array in yaml come segue:

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

Proprietà obbligatorie

Tutte le proprietà definite sono facoltative per impostazione predefinita. Per contrassegnare una proprietà come obbligatoria, basta annotare la proprietà con required: true. Una proprietà può essere contrassegnata come facoltativa annotandola con required: false.

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

I valori vuoti di tipo string, datetime e icon e le liste vuote di categories, groups e tags contano come mancanti: le proprietà obbligatorie le rifiutano e le proprietà facoltative ne saltano la validazione. Il valore false conta come impostato.

Validazioni personalizzate

Per certi tipi di proprietà, esiste un supporto integrato per le validazioni personalizzate, che possono essere dichiarate annotando la proprietà con la parola chiave validations.

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

Validazioni per i tipi string

  • min_length: Lunghezza minima della proprietà. Il valore della parola chiave deve essere un intero.
  • max_length: Lunghezza massima della proprietà. Il valore della parola chiave deve essere un intero.
  • url: Valida che la proprietà sia un URL valido. Il valore della parola chiave può essere true/false.

Validazioni per i tipi integer e float

  • min: Valore minimo della proprietà. Il valore della parola chiave deve essere un intero.
  • max: Valore massimo della proprietà. Il valore della parola chiave deve essere un intero.

Validazioni per i tipi tags, groups e categories

  • min: Numero minimo di record per la proprietà. Il valore della parola chiave deve essere un intero.
  • max: Numero massimo di record per la proprietà. Il valore della parola chiave deve essere un intero.

Risoluzione dell’appartenenza ai gruppi

Le impostazioni degli oggetti possono risolvere le proprietà type: groups in un valore booleano per l’utente attuale. Questo è utile quando il codice del tema deve sapere solo se l’utente attuale appartiene a uno dei gruppi configurati, poiché currentUser.groups include solo i gruppi visibili all’utente.

Aggiungi resolve_group_membership: true alla proprietà 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

L’interfaccia di amministrazione e il valore dell’impostazione salvato utilizzano ancora l’array groups originale. Nell’oggetto settings del runtime frontend, Discourse rimuove gli ID dei gruppi da ogni oggetto e aggiunge un booleano con lo stesso nome di proprietà, preceduto da user_in_:

for (const section of settings.menu_sections) {
  if (section.user_in_groups) {
    // L'utente appartiene ad almeno un gruppo selezionato per questa sezione.
  }
}

Questa opzione è valida solo per le proprietà dello schema degli oggetti con type: groups. Funziona anche con gli schemi di oggetti nidificati e con i gruppi automatici come logged_in_users e anonymous_users.

Struttura degli oggetti nidificati

Un oggetto può anche avere una proprietà che contiene un array di oggetti. Per creare una struttura di oggetti nidificati, una proprietà può anche essere annotata con type: objects e la relativa definizione di 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

Descrizione e localizzazione dell’impostazione

Per aggiungere una descrizione per l’impostazione nella locale en, crea un file locales/en.yml con il seguente formato, data la seguente impostazione del tema di 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: Questa è una descrizione per l'impostazione del tema sections
        schema:
          properties:
            name:
              label: Nome
              description: La descrizione per la proprietà
            links:
              name:
                label: Nome
                description: La descrizione per la proprietà
              url:
                label: URL
                description: La descrizione per la proprietà

Questo documento è sottoposto a controllo di versione - suggerisci modifiche su github.

16 Mi Piace

Rimango da convincere che la deprecazione dello stile dello schema JSON sia una buona idea.

Sebbene questi possano diventare piuttosto complessi e non siano i formati più “amichevoli per gli sviluppatori” (quindi questo è un ottimo cambiamento a riguardo), ci sono strumenti online per convalidare gli schemi JSON che è un modo davvero utile per convalidare sia lo schema che contro qualsiasi dato predefinito.

ad es. https://www.jsonschemavalidator.net/

Come funzionerà in questo nuovo mondo?

2 Mi Piace

Quando si carica un tema, convalidiamo i dati predefiniti rispetto allo schema definito. Detto questo, al momento non stiamo convalidando la validità della definizione dello schema, ma non sarebbe difficile farlo. Anche per l’impostazione dello schema json attuale, non credo che stiamo convalidando i dati predefiniti rispetto allo schema definito.

La nostra attuale implementazione delle impostazioni del tipo di schema json è in qualche modo difettosa per molti versi, il più ovvio dei quali è l’editor nell’interfaccia di amministrazione. Ne abbiamo discusso internamente e abbiamo deciso che è molto più facile per noi mantenere un formato di schema limitato definito da noi invece di consentire tutte le possibilità che derivano dallo schema json.

2 Mi Piace

Alcune fantastiche funzionalità qui:

  • puoi sbarazzarti di JSON.parse e accedere direttamente all’impostazione per ottenere l’oggetto, il che è davvero bello.

  • il validatore di URL!

:chefs_kiss: :chefs_kiss:

5 Mi Piace

C’è un modo per rispettare più righe nell’editor?

Questo predefinito funziona:

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

Ma una volta modificato, i ritorni a capo vengono persi

Inoltre, sarebbe bello avere un tipo “text” che possa memorizzare dati più lunghi e magari esporre un editor “text-area” più grande.

5 Mi Piace

Ecco alcuni feedback:

2 Mi Piace

Ho notato questo ed è stato corretto in

1 Mi Piace

Saremo in grado di riordinare gli elementi sull’interfaccia?

Ad esempio, questo è l’editor delle impostazioni dell’oggetto sul componente del tema easy footer. Al momento non posso riorganizzare nessun elemento:

4 Mi Piace

Volevo richiedere anche questa funzionalità! :+1:


A parte questo, sarebbe utile se il primo post contenesse informazioni sulla proprietà identifier.

Prima di guardare l’immagine di Nolo qui sopra, pensavo che fosse impossibile sostituire l’etichetta figlio predefinita con un valore di proprietà. Dopo aver esaminato il codice, ho trovato la proprietà identifier.

4 Mi Piace

Il riordino è certamente qualcosa che è stato sollevato internamente. Cercherò di implementarlo questa settimana.

Preso nota. Aggiornerò il primo post sulla proprietà identifier.

5 Mi Piace

Sì, per sostituire il sistema JSON (che presto diventerà obsoleto?) è necessario che corrisponda o superi la vecchia interfaccia:

inclusa l’ordinazione.

1 Mi Piace

Ciao, ci sono piani per supportare presto altri tipi di campo?

Ad esempio;

  • una long_string con formato markdown; forse con barra degli strumenti personalizzabile,
  • un campo date (con regole di validazione),
  • un campo color (con regole di validazione)?
1 Mi Piace

Non ci sono piani attuali, anche se concordo sul fatto che sarebbe utile. Mi piacerebbe un campo icona per me.

8 Mi Piace

Per mia esperienza, sembra funzionare come preset salvati. In questo esempio le prime 2 voci potrebbero beneficiare di questi preset, ma qualsiasi cosa dopo, tutte le nuove voci appariranno inizialmente vuote.

Ciò significa anche che non possiamo impostare valori predefiniti per ogni campo. Ad esempio, se voglio che una casella di controllo sia selezionata per impostazione predefinita, non posso farlo.

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 non funzionerà come previsto.

Ci potrebbe essere un modo per impostare i valori predefiniti per campo, per ogni voce creata?

Esiste un modo per importare le proprietà degli oggetti in variabili in Sass?

Puoi sempre analizzare la stringa, ma non sembra una buona idea promuoverla in questo modo. :sweat_smile:

1 Mi Piace

Grazie per aver condiviso l’esempio! Anche se sì… non sembra molto allettante :upside_down_face:

1 Mi Piace

Per curiosità, senza perdere troppo tempo a cercare, a che punto siamo con questo?

2 Mi Piace

Sì, non è molto buono, non farlo. :smile:. È stato più un tentativo di vedere se fosse possibile, ma non un approccio ragionevole.
Sono d’accordo con te; sarebbe bello avere un modo diretto! :+1:

Mi piacerebbe saperlo anche a me!
Inoltre, se non erro, quella sarebbe l’unica funzionalità mancante in parità con json_schema.

2 Mi Piace

Stavo cercando che il tipo di caricamento fosse disponibile, ma non lo è. Una rapida occhiata al core mostra che i tipi topic, post e upload sono stati implementati lato server ma non nel front end. C’è un motivo specifico per questo? :thinking: