Objekttyp für Thema-Einstellung

Wir führen einen neuen type: objects bei den unterstützten Typen für Theme-Einstellungen ein, der den bestehenden Typ json_schema ersetzen kann, den wir demnächst als veraltet markieren möchten.

Definieren einer objects-Theme-Einstellung

Um eine objects-Theme-Einstellung zu erstellen, definieren Sie zunächst einen Schlüssel der obersten Ebene, genau wie bei jeder anderen Theme-Einstellung, der als Name der Einstellung dient.

links: ...

Fügen Sie anschließend die Schlüsselwörter type, default und schema zur Einstellung hinzu.

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

type: objects gibt an, dass es sich um eine Einstellung vom Typ objects handelt, während die default: []-Annotation den Standardwert der Einstellung auf ein leeres Array setzt. Beachten Sie, dass der Standardwert auch als Array von Objekten festgelegt werden kann, was wir einmal gezeigt haben, nachdem das schema definiert wurde.

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

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

Als Nächstes fügen wir das Schlüsselwort properties zum Schema hinzu, damit wir definieren und validieren können, 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 besagt, dass das link-Objekt eine name-Eigenschaft vom Typ string hat, was bedeutet, dass für diese Eigenschaft nur Zeichenfolgenwerte akzeptiert werden. Derzeit werden folgende Typen unterstützt:

  • string: Der Wert der Eigenschaft wird als Zeichenfolge gespeichert. Setzen Sie textarea: true, um ein sich erweiterndes Textfeld zu verwenden:

    description:
      type: string
      textarea: true
      validations:
        max_length: 500
    
  • 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 Anhang-URL

  • enum: Der Wert der Eigenschaft muss einer der im Schlüsselwort choices definierten Werte sein.

    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.

  • icon: Der Wert der Eigenschaft ist der Name eines einzelnen Symbols aus dem Discourse-Symbolset. Ausgewählte Symbole werden automatisch zum Sprite-Sheet hinzugefügt, sodass sie ohne separate Registrierung gerendert werden können.

Mit dem definierten Schema kann der Standardwert der Einstellung nun durch Definieren eines Arrays in YAML wie folgt festgelegt 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 sie mit required: false annotiert wird.

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

Leere string-, datetime- und icon-Werte sowie leere categories-, groups- und tags-Listen gelten als fehlend: Erforderliche Eigenschaften lehnen sie ab, und optionale Eigenschaften überspringen ihre Validierungen. false zählt als gesetzt.

Benutzerspezifische Validierungen

Für bestimmte Eigenschaftstypen gibt es eine eingebaute Unterstützung für benutzerspezifische 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_length: 1
          max_length: 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: Maximale Lä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: Minimalwert 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 Datensätze für die Eigenschaft. Der Wert des Schlüsselworts muss eine Ganzzahl sein.
  • max: Maximale Anzahl der Datensätze für die Eigenschaft. Der Wert des Schlüsselworts muss eine Ganzzahl sein.

Auflösen der Gruppenzugehörigkeit

Objekte-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 settings-Objekt der Frontend-Laufzeitumgebung entfernt Discourse die Gruppen-IDs aus jedem Objekt und fügt einen booleschen Wert mit demselben Eigenschaftsnamen hinzu, der durch das Präfix user_in_ gekennzeichnet ist:

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

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

Verschachtelte Objekte-Struktur

Ein Objekt kann auch eine Eigenschaft enthalten, die ein Array von Objekten enthält. Um eine verschachtelte Objekte-Struktur 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

Einstellungssbeschreibung und Lokalisierung

Um eine Beschreibung für die Einstellung im en-Lokalisierungsschema hinzuzufügen, erstellen Sie eine Datei locales/en.yml mit dem folgenden Format für die angegebene objects-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
en:
  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 ist versionskontrolliert – Änderungen können auf GitHub vorgeschlagen werden.

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: