Wertausdrücke (Value Expressions)

Zuletzt aktualisiert: 20. Juli 2026

Jede Stelle in einem Script, an der ein Wert benötigt wird (URL, Anfrage-body, Feldwert, Bedingung, Filterwert, Ziel-id usw.), ist eine der drei folgenden Formen. Dieses Dokument beschreibt diese drei Formen, woher die Werte kommen (die Kontextwurzeln) und die für WEEGLOO-Daten spezifischen Regeln der Locale-Map. Alle Felder im Statement-Katalog folgen diesen Regeln.

Die drei Formen

FormRegelBeispiel
Referenz (reference)Löst das { /json-pointer } innerhalb eines Strings gegen den Kontext auf."{ /payload/fields/title }"
Literal (literal)Ein Wert ohne { /ptr } (String, Zahl, Boolean, Objekt, Array). Wird unverändert verwendet."draft", 42, true, { "a": 1 }
Operationen und Bedingungen (JsonLogic)Ein Objekt mit einem einzelnen Operator als Schlüssel. Die Operanden sind wiederum Wertausdrücke (Referenz, Literal, Verschachtelung).{ "+": [ "{ /vars/n }", 1 ] }

Die drei Formen lassen sich verschachteln. Man kombiniert sie, indem man eine Referenz als JsonLogic-Operanden einsetzt und das Ergebnis einer Referenz wiederum in eine Operation gibt.

Referenz: { /json-pointer }

In die geschweiften Klammern kommt ein RFC 6901 JSON Pointer (muss mit / beginnen). Leerzeichen um die geschweiften Klammern sind erlaubt ({ /a/b } ist gleichbedeutend mit {/a/b}).

Einzelner Pointer und gemischtes Template: Typregeln

  • Ist der gesamte String ein einzelner Pointer, bleibt der ursprüngliche Typ des Werts erhalten (Zahl bleibt Zahl, Objekt bleibt Objekt, Array bleibt Array).
  • Wird es mit literalem Text vermischt, erfolgt eine String-Verkettung (concatenation).
"{ /payload/fields/count }"                 // wenn Zahl, dann Zahl unverändert (z. B. 42)
"{ /payload/fields/tags }"                  // wenn Array, dann Array unverändert
"page-{ /payload/fields/n }-of-10"          // String-Verkettung → "page-42-of-10"
"Bearer { /payload/fields/token }"          // String-Verkettung → "Bearer abc123"

Fehlende Werte und Escaping

  • Fehlt der Pfad oder ist der Wert leer, wird bei einem einzelnen Pointer null und bei einem gemischten Template ein leerer String verwendet.
  • Um { als Literal zu verwenden, escapen Sie es mit \{ (an dieser Stelle wird es nicht als Pointer interpretiert).

Kontextwurzeln: Woher die Werte kommen

Das oberste Segment von { /pointer } ist eines der folgenden fünf.

WurzelInhalt
/payloadDas beim Aufruf übergebene JSON-payload (Eingabe). Beispiel: { /payload/fields/email }
/headersDie beim Aufruf übergebenen HTTP-Anfrageheader. Die Schlüssel sind kleingeschrieben und pro Name gibt es einen einzelnen Wert. Beispiel: { /headers/authorization }
/<name>Das Ergebnis eines vorausgehenden statement mit diesem name. Beispiel: { /order/sys/id }
/vars/<name>Eine mit SetVar deklarierte, script-scoped veränderliche Variable. Beispiel: { /vars/total }
/errorWird nur innerhalb des catch-Blocks von Try verwendet. Der abgefangene Fehler { message, statement }. Beispiel: { /error/message }

Form des statement-Ergebnisses

Die Form des Ergebnisses eines statement mit name unterscheidet sich je Typ.

statementErgebnisformReferenzbeispiel
Http{ status, body }{ /resp/status }, { /resp/body/choices/0/message/content }
ResourceCreate, ResourceRead (einzeln), ResourceFind (einzeln)Die Ressource selbst{ /post/sys/id }, { /post/fields/title/en-US }
ResourcePageRead{ items, next }{ /page/items/0/sys/id }, { /page/next }
  • ResourceFind bindet null, wenn es keine Übereinstimmung gibt. Mit { "==": [ "{ /found }", null ] } verzweigt man nach dem Vorhandensein.
  • ResourceRead (einzeln) ist ein Fehler, wenn das Ziel nicht existiert (mit Try behandelbar). Ausführlich behandelt unter Ressourcen-Lesen im Statement-Katalog.

Operationen und Bedingungen: JsonLogic

Wenn eine Berechnung oder Bedingung nötig ist, verwenden Sie das Operatorobjekt der jsonlogic.com-Spezifikation.

  • Der Datenzugriff erfolgt nicht über vanilla var (dot-path), sondern einheitlich über { /ptr }-Referenzen. Die Engine löst zuerst die Pointer der Operanden auf und wendet dann den Operator an.
  • Ist der Schlüssel eines Objekts mit einem einzelnen Schlüssel ein registrierter Operator, wird es als Operation behandelt, andernfalls als gewöhnliches Objekt.

Operatortabelle

KategorieOperatorBedeutung und Beispiel
Bedingungif (Alias ?:){ "if": [Bedingung, Wahr-Wert, Bedingung2, Wahr-Wert2, …, Standardwert] }. Wert der ersten wahren Bedingung, sonst der letzte Standardwert.
Logikand, orKurzschlussauswertung. and gibt das erste falsy (oder das letzte), or das erste truthy (oder das letzte) als Wert zurück.
Logik! (not), !! (to-bool){ "!": x } negiert truthy, { "!!": x } liefert, ob truthy. Für Existenzprüfungen wird häufig !! verwendet.
Gleichheit==, !=Loser Vergleich (Vergleich nach erzwungener Zahlenkonvertierung. "1"==1 ist wahr).
Gleichheit===, !==Strikter Vergleich (einschließlich Typ).
Vergleich<, <=, >, >=Verkettbar: { "<": [1,2,3] } ist 1<2 AND 2<3. Nicht in eine Zahl umwandelbar (NaN) ergibt false.
Arithmetik+Summe aller Operanden.
Arithmetik-Bei einem Operanden Vorzeichenumkehr, bei zwei Operanden Subtraktion.
Arithmetik*, /, %Multiplikation, Division, Rest.
Aggregationmin, maxMinimum und Maximum der Operanden.
StringcatVerkettet alle Operanden zu einem String.
Enthaltenseinin{ "in": [needle, haystack] }. Ist haystack ein String, Teilstring-Prüfung; ist es eine Collection, Element-Enthaltensein.
ArraymergeFlacht mehrere Arrays oder Werte zu einem einzigen Array ab (für kumulatives Sammeln).

Array-Iterationsoperatoren (map, filter, reduce, all, some, none) werden nicht unterstützt. Script iteriert über Arrays mit Loop (Loop im Statement-Katalog).

Zahlenkonvertierung und Beispiele

Die Regeln der Zahlenkonvertierung sind wie folgt: Zahlen bleiben unverändert, true wird zu 1, false zu 0, Strings werden geparst (ist der String nicht parsbar, ergibt sich ein Berechnungsfehlerwert) und null wird zu 0 konvertiert.

{ "-":  [ "{ /wallet/fields/balance/en-US }", "{ /payload/fields/cost }" ] }   // Guthaben - Kosten
{ "<":  [ "{ /wallet/fields/balance/en-US }", "{ /payload/fields/cost }" ] }   // Guthaben < Kosten → boolean
{ "and": [ { "<": [ "{ /a/body/risk }", 0.5 ] }, { ">=": [ "{ /b/body/score }", 700 ] } ] }
{ "cat": [ "id-", "{ /payload/sys/id }" ] }                                    // "id-<uuid>"
{ "!!": "{ /found/sys/id }" }                                                  // wenn vorhanden, true
{ "merge": [ "{ /vars/ids }", [ "{ /row/sys/id }" ] ] }                        // ein Element im Array akkumulieren
{ "if": [ "{ /page/next }", "{ /page/next }", "END" ] }                        // wenn next vorhanden, next, sonst "END"

Auswertung von wahr und falsch (Truthiness)

if, and, or, !, !! sowie If.condition und Loop.while bestimmen wahr und falsch nach den folgenden Regeln.

  • falsy: null, false, die Zahl 0, der leere String "", leere Collection (leeres Array).
  • truthy: alles andere (Zahlen ungleich 0, nicht leere Strings und Arrays, alle Objekte).

Auch Schlüssel können referenziert werden

Auch der Schlüssel einer Map wie fields unterstützt { /ptr }-Referenzen. Der Schlüssel wird zur Laufzeit aufgelöst.

"fields": { "{ /payload/fields/fieldName }": { "en-US": "{ /payload/fields/fieldValue }" } }

Lösen sich zwei Schlüssel zum selben Wert auf, kommt es zu einer Kollision und einem Engine-Fehler.

Locale-Map (LocaleValueMap): Regeln speziell für Content und Media

Jedes Feld von WEEGLOO Content und Media ist keine einzelne Wertangabe, sondern eine Map je Locale (z. B. balance als { "en-US": 1, "ko-KR": 10 }). Daher muss beim Lesen und Schreiben die Locale mitbehandelt werden. Auch bei Media sind title und description (Skalar) sowie file (Ingest-Anweisung) Locale-Maps. JSON, das wie /payload oder eine HTTP-Antwort weder Content noch Media ist, ist von dieser Regel nicht betroffen (es behält die vom Schema festgelegte Struktur, und ein Skalar bleibt ein Skalar).

Lesen

  • Um einen Skalar zu erhalten, geben Sie auch die Locale an: { /<name>/fields/<field>/<locale> } (z. B. { /post/fields/title/en-US }).
  • Ohne Locale ({ /<name>/fields/<field> }) ergibt sich das gesamte Objekt der Locale-Map.
  • Ein Feld mit localized:false liegt nur im Bucket der Standard-Locale vor, daher liest man es mit dem Code dieser Standard-Locale.

Schreiben (fields bei ResourceCreate, ResourceUpdate, ResourcePatch)

Der Wert ist eine Locale-Map { "<locale>": <skalarer Wertausdruck> }. Symmetrisch zum Lesen.

"fields": {
  "title":  { "en-US": "Hello", "ko-KR": "안녕" },   // mehrere Locales als Buckets auflisten
  "status": { "en-US": "paid" }
}
  • ResourceCreate muss für jedes befüllte Feld den Bucket der Standard-Locale des Space enthalten (default-locale-Regel).
  • ResourceUpdate ist eine vollständige Ersetzung. Felder und Locales, die nicht in fields stehen, werden entfernt (einschließlich file).
  • ResourcePatch aktualisiert nur die angegebenen Felder und Buckets (die übrigen Felder und Locales bleiben erhalten).
  • Löschen mit literalem null: Ist der Wert literales null, wird der Bucket (field, locale) gelöscht (Standard, um bei Patch eine bestimmte Locale zu leeren). "" (leerer String) ist keine Löschung, sondern das Setzen eines leeren Werts. Wird ein Wertausdruck ({ /ptr }) zur Laufzeit als null ausgewertet, ist das keine Löschung, sondern ein Fehler (ein fehlendes payload wird nicht stillschweigend verschluckt). Gelöscht wird nur mit literalem null.
  • Media file: Der Wert ist kein Skalar, sondern eine Ingest-Anweisung { "source": …, "encoding": "url"|"base64" }. Schreibvorgänge mit Datei sind nur im Async-Modus möglich (ResourceCreate im Statement-Katalog).
  • Ein Feld mit localized:false wird nur in den Bucket der Standard-Locale eingetragen.
  • Auch der Locale-Code (der Map-Schlüssel) kann per { /ptr } referenziert werden (siehe oben Auch Schlüssel können referenziert werden). Wird verwendet, um dynamische Locales zu erzeugen.

Komfortfeld locale

Gibt man ResourceCreate, ResourceUpdate oder ResourcePatch ein locale mit, umschließt die Engine jeden Wert in fields automatisch mit einem Bucket { <locale>: Wert }. Man muss also nur Skalare übergeben.

// die beiden folgenden sind identisch
{ "type": "ResourceCreate", "resource": "Content", "contentType": { "sys": { "id": "ct_post" } },
  "locale": "en-US", "fields": { "title": "Hello" } }
 
{ "type": "ResourceCreate", "resource": "Content", "contentType": { "sys": { "id": "ct_post" } },
  "fields": { "title": { "en-US": "Hello" } } }

Gibt man locale mit und verschachtelt im Wert bereits eine Locale-Map ({ "en-US": … }), entsteht mit { <locale>: { "en-US": … } } eine doppelte Verschachtelung (Fehler des Autors). Vereinheitlichen Sie es so: mit locale nur Skalare, ohne locale nur explizite Locale-Maps.

Locale bei where und order

  • Bei where und order wendet die Engine auf fields.X automatisch die Standard-Locale des Space an (wie bei der CMA-Abfrage).
  • Um eine bestimmte Locale anzusteuern, geben Sie sie mit fields.X.<locale> explizit an.
"where": { "fields.slug": { "eq": "{ /payload/fields/slug }" } }   // slug der Standard-Locale
"where": { "fields.title.ko-KR": { "prefix": "안" } }              // bestimmte Locale