Objekttyp für Theme-Einstellung

Wir führen einen neuen type: objects für die unterstützten Typen für Theme-Einstellungen ein, der verwendet werden kann, um den bestehenden json_schema-Typ zu ersetzen, den wir in naher Zukunft veralten lassen wollen.

Definieren einer Theme-Einstellung vom Typ objects

Um eine Theme-Einstellung vom Typ objects zu erstellen, definieren Sie zunächst einen Schlüssel auf oberster Ebene, genau wie bei jeder anderen Theme-Einstellung, der als Name der Einstellung verwendet wird.

links: ...

Fügen Sie als Nächstes die Schlüsselwörter type, default und schema zur Einstellung hinzu.

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

type: objects gibt an, dass dies eine Einstellung vom Typ objects ist, während die Annotation default: [] den Standardwert der Einstellung auf ein leeres Array setzt. Beachten Sie, dass der Standardwert auch auf ein Array von Objekten gesetzt werden kann, was wir demonstrieren werden, sobald das schema definiert ist.

Um das Schema zu definieren, definieren Sie zunächst den name des Schemas wie folgt:

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

Als Nächstes fügen wir dem Schema das Schlüsselwort properties hinzu, das es uns ermöglicht, zu definieren und zu validieren, wie jedes Objekt aussehen soll.

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

Im obigen Beispiel geben wir an, dass das link-Objekt eine name-Eigenschaft hat. Um den erwarteten Datentyp zu definieren, muss jede Eigenschaft das Schlüsselwort type definieren.

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

Die obige Schema-Definition gibt an, dass das link-Objekt eine name-Eigenschaft vom Typ string hat, was bedeutet, dass für die Eigenschaft nur String-Werte akzeptiert werden. Derzeit werden die folgenden Typen unterstützt:

  • string: Der Wert der Eigenschaft wird als String gespeichert.
  • integer: Der Wert der Eigenschaft wird als Ganzzahl gespeichert.
  • float: Der Wert der Eigenschaft wird als Gleitkommazahl gespeichert.
  • boolean: Der Wert der Eigenschaft ist true oder false.
  • upload: Der Wert der Eigenschaft ist die URL des Anhangs.
  • enum: Der Wert der Eigenschaft muss einer der Werte sein, die im Schlüsselwort choices definiert sind.
    links:
      type: objects
      default: []
      schema:
        name: link
        properties:
          name:
            type: enum
            choices:
              - name 1
              - name 2
              - name 3
    
  • categories: Der Wert der Eigenschaft ist ein Array gültiger Kategorie-IDs.
  • groups: Der Wert der Eigenschaft ist ein Array gültiger Gruppen-IDs.
  • tags: Der Wert der Eigenschaft ist ein Array gültiger Tag-Namen.

Mit dem definierten Schema kann der Standardwert der Einstellung nun durch die Definition eines Arrays in YAML wie folgt gesetzt werden:

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

Erforderliche Eigenschaften

Alle definierten Eigenschaften sind standardmäßig optional. Um eine Eigenschaft als erforderlich zu markieren, annotieren Sie die Eigenschaft einfach mit required: true. Eine Eigenschaft kann auch als optional markiert werden, indem die Eigenschaft mit required: false annotiert wird.

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

Benutzerdefinierte Validierungen

Für bestimmte Eigenschaftstypen gibt es integrierte Unterstützung für benutzerdefinierte Validierungen, die durch Annotieren der Eigenschaft mit dem Schlüsselwort validations deklariert werden können.

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

Validierungen für string-Typen

  • min_length: Mindestlänge der Eigenschaft. Der Wert des Schlüsselworts muss eine Ganzzahl sein.
  • max_length: Maximallänge der Eigenschaft. Der Wert des Schlüsselworts muss eine Ganzzahl sein.
  • url: Validiert, dass die Eigenschaft eine gültige URL ist. Der Wert des Schlüsselworts kann true/false sein.

Validierungen für integer- und float-Typen

  • min: Mindestwert der Eigenschaft. Der Wert des Schlüsselworts muss eine Ganzzahl sein.
  • max: Maximalwert der Eigenschaft. Der Wert des Schlüsselworts muss eine Ganzzahl sein.

Validierungen für tags, groups und categories-Typen

  • min: Mindestanzahl der Einträge für die Eigenschaft. Der Wert des Schlüsselworts muss eine Ganzzahl sein.
  • max: Maximalanzahl der Einträge für die Eigenschaft. Der Wert des Schlüsselworts muss eine Ganzzahl sein.

Auflösen der Gruppenmitgliedschaft

Objekt-Einstellungen können type: groups-Eigenschaften für den aktuellen Benutzer in einen booleschen Wert auflösen. Dies ist nützlich, wenn der Theme-Code nur wissen muss, ob der aktuelle Benutzer in einer der konfigurierten Gruppen ist, da currentUser.groups nur Gruppen enthält, die für den Benutzer sichtbar sind.

Fügen Sie resolve_group_membership: true zur groups-Eigenschaft hinzu:

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

Die Admin-UI und der gespeicherte EinstellungsWert verwenden weiterhin das ursprüngliche groups-Array. Im Frontend-Laufzeit-settings-Objekt entfernt Discourse die Gruppen-IDs aus jedem Objekt und fügt einen booleschen Wert mit demselben Eigenschaftsnamen vorangestellt von user_in_ hinzu:

for (const section of settings.menu_sections) {
  if (section.user_in_groups) {
    // Benutzer ist in mindestens einer ausgewählten Gruppe für diesen Abschnitt.
  }
}

Diese Option ist nur für Objektschema-Eigenschaften mit type: groups gültig. Sie funktioniert auch mit verschachtelten Objektschemas und mit automatischen Gruppen wie logged_in_users und anonymous_users.

Verschachtelte Objektstruktur

Ein Objekt kann auch eine Eigenschaft haben, die ein Array von Objekten enthält. Um eine verschachtelte Objektstruktur zu erstellen, kann eine Eigenschaft auch mit type: objects und der zugehörigen schema-Definition annotiert werden.

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

Einstellungsbeschreibung und Lokalisierung

Um eine Beschreibung für die Einstellung im en-Lokalisierungsdatei zu erstellen, erstellen Sie eine Datei locales/en.yml mit dem folgenden Format für die folgende objects-Typ-Theme-Einstellung.

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
de:
  theme_metadata:
    settings:
      sections:
        description: Dies ist eine Beschreibung für die sections-Theme-Einstellung
        schema:
          properties:
            name:
              label: Name
              description: Die Beschreibung für die Eigenschaft
            links:
              name:
                label: Name
                description: Die Beschreibung für die Eigenschaft
              url:
                label: URL
                description: Die Beschreibung für die Eigenschaft

Dieses Dokument wird versioniert – schlagen Sie Änderungen auf GitHub vor.

16 „Gefällt mir“

Ich bin noch nicht davon überzeugt, dass die Abschaffung des JSON-Schema-Stils eine gute Idee ist.

Obwohl diese ziemlich komplex werden können und nicht die „entwicklerfreundlichsten“ Formate sind (daher ist dies in dieser Hinsicht eine großartige Änderung), gibt es Online-Tools zur Validierung von JSON-Schemas, die eine wirklich nützliche Möglichkeit sind, sowohl das Schema als auch gegen Standarddaten zu validieren.

z. B. https://www.jsonschemavalidator.net/

Wie wird das in dieser neuen Welt funktionieren?

2 „Gefällt mir“

Beim Hochladen eines Themas validieren wir die Standarddaten gegen das definierte Schema. Das heißt, wir validieren derzeit nicht, ob die Schemadefinition gültig ist, aber es wäre nicht schwer für uns, dies zu tun. Selbst für die aktuelle JSON-Schema-Einstellung validieren wir meiner Meinung nach die Standarddaten nicht gegen das definierte Schema.

Unsere aktuelle Implementierung von JSON-Schema-Typ-Einstellungen ist in vielerlei Hinsicht fehlerhaft, wobei der offensichtlichste der Editor in der Admin-Oberfläche ist. Wir haben dies intern besprochen und entschieden, dass es für uns viel einfacher ist, ein von uns definiertes, begrenztes Schemaformat beizubehalten, anstatt alle Möglichkeiten zuzulassen, die mit JSON-Schema einhergehen.

2 „Gefällt mir“

Einige coole Funktionen hier:

  • Sie können JSON.parse loswerden und direkt auf die Einstellung zugreifen, um das Objekt zu erhalten, was wirklich schön ist.

  • Der URL-Validator!

:chefs_kiss: :chefs_kiss:

5 „Gefällt mir“

Werden mehrere Zeilen im Editor berücksichtigt?

Dies funktioniert standardmäßig:

- name: markdown
  value: > 
    ## Überschrift
      * erster Punkt
      * zweiter Punkt

Aber sobald Sie dies bearbeiten, gehen die Wagenrückläufe verloren

Außerdem wäre es schön, einen „Text“-Typ zu haben, der längerformige Daten speichern und möglicherweise einen größeren „Textbereich“-Editor bereitstellen könnte.

5 „Gefällt mir“

Hier sind einige Rückmeldungen:

2 „Gefällt mir“

Ich habe das bemerkt und es wurde in
FIX: 404 when visiting theme setting objects editor for theme compone… · discourse/discourse@25bcee4 · GitHub behoben

1 „Gefällt mir“

Werden wir in der Lage sein, Elemente in der Benutzeroberfläche neu zu bestellen?

Zum Beispiel ist das der Objekt-Einstellungen-Editor in der Easy Footer Theme-Komponente. Ich kann derzeit keine Elemente neu anordnen:

4 „Gefällt mir“

Ich wollte diese Funktion auch beantragen! :+1:


Nebenbei bemerkt, wäre es hilfreich, wenn der erste Beitrag Informationen über die identifier-Eigenschaft enthalten würde.

Bevor ich mir das Bild von Nolo oben angesehen habe, dachte ich, es sei unmöglich, die Standard-Kindbezeichnung durch einen Eigenschaftswert zu ersetzen. Nachdem ich mir den Code angesehen hatte, fand ich die identifier-Eigenschaft.

4 „Gefällt mir“

Das Neuanordnen ist sicherlich etwas, das auch intern angesprochen wurde. Ich werde versuchen, dies diese Woche zu implementieren.

Zur Kenntnis genommen. Ich werde den ersten Beitrag über die identifier-Eigenschaft aktualisieren.

5 „Gefällt mir“

Ja, um das (bald veraltete?) JSON-System zu ersetzen, muss es die alte Schnittstelle:\n\n

\n\nentsprechen oder übertreffen, einschließlich der Reihenfolge.

1 „Gefällt mir“

Hallo, gibt es Pläne, bald andere Feldtypen zu unterstützen?

Zum Beispiel:

  • ein long_string im Markdown-Format; vielleicht mit anpassbarer Symbolleiste,
  • ein date-Feld (mit Validierungsregeln),
  • ein color-Feld (mit Validierungsregeln)?
1 „Gefällt mir“

Es gibt derzeit keinen Plan, obwohl ich zustimme, dass es nützlich wäre. Ich selbst hätte gerne ein icon-Feld.

8 „Gefällt mir“

Meiner Erfahrung nach scheint dies wie gespeicherte Voreinstellungen zu funktionieren. In diesem Beispiel könnten die ersten 2 Einträge von diesen Voreinstellungen profitieren, aber alles danach, alle neuen Einträge, werden zunächst leer angezeigt.

Dies bedeutet auch, dass wir keine Standardwerte für jedes Feld festlegen können. Wenn ich zum Beispiel eine Checkbox haben möchte, die im aktivierten Zustand beginnt, kann ich das nicht tun.

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 wird dort nicht wie erwartet funktionieren.

Gibt es eine Möglichkeit, die Standardwerte pro Feld für jeden erstellten Eintrag festzulegen?

Gibt es eine Möglichkeit, Objekt-Eigenschaften in Sass in Variablen zu importieren?

Sie können die Zeichenkette immer parsen, aber das klingt nicht nach einer guten Idee, dies so zu fördern. :sweat_smile:

1 „Gefällt mir“

Danke für das Beispiel! Obwohl ja… es sieht nicht so verlockend aus :upside_down_face:

1 „Gefällt mir“

Interessenshalber, ohne zu viel Zeit mit Suchen zu verbringen, wie weit sind wir damit?

2 „Gefällt mir“

Ja, es ist nicht sehr gut, tun Sie es nicht. :smile:. Es war mehr ein Versuch zu sehen, ob es möglich ist, aber kein vernünftiger Ansatz.
Ich stimme Ihnen zu; es wäre schön, einen direkten Weg zu haben! :+1:

Das würde ich auch gerne wissen!
Außerdem wäre das, wenn ich richtig liege, die einzige fehlende Funktion zur json_schema-Parität.

2 „Gefällt mir“

Ich habe nach dem Upload-Typ gesucht, aber er ist nicht verfügbar. Ein kurzer Blick in den Core zeigt, dass die Typen Topic, Post und Upload serverseitig implementiert wurden, aber nicht im Frontend. Gibt es dafür einen bestimmten Grund? :thinking: