Wertausdrücke (Value Expressions)

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. Es gibt nur zwei Ausnahmen: Das pattern von Regex und das key von Cache werden ausschließlich als Literal geschrieben, und ein { /pointer } darin wird nicht zu einem Wert. 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). Je nach Stelle benötigt der Operator ein $.{ "$+": [ "{ /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.

Datenstelle und Ausdrucksstelle: Wann man $ voranstellt

Dasselbe JSON wird je nach Stelle unterschiedlich gelesen. Entscheidend ist, wem die Schlüssel an dieser Stelle gehören. Die Schlüssel von fields sind die Feld-ids des Content Type und die Schlüssel von Http.body stammen aus dem Schema der aufgerufenen API. An solchen Stellen müssen cat oder in deshalb Feldnamen sein und keine Operatoren.

StelleBetroffene FelderWie sie gelesen wird
Datenstellefields (ResourceCreate, ResourceUpdate, ResourcePatch), Http.body, Return.value, SetVar.value, Cache.value, Cache.defaultValueEin Schlüssel ohne $ ist immer ein Feldname. Für eine Operation stellen Sie ein $ voran.
AusdrucksstelleIf.condition, Loop.while, versionDer gesamte Wert ist ein Ausdruck. Als Operator geht cat genauso wie $cat.
Template-StelleAlles Übrige (url, method, headers[].value, locale, order, over, target.sys.id, die Felder von EmailSend, die Wertfelder von Signature, Hash und Regex)Es ist ein String, daher kommt nur { /pointer } hinein.
Nur LiteralRegex.pattern, Cache.keyEs ist kein Wertausdruck. Ein { /pointer }, das in Regex.pattern steht, wird nicht ersetzt, sondern Teil des Patterns.

Die Regeln passen in zwei Zeilen.

  1. An einer Datenstelle ist ein Schlüssel ohne $ immer ein Feldname. Für eine Operation stellen Sie dem Operator ein $ voran.
  2. Ist man einmal mit $ in einen Ausdruck eingetreten, ist alles darin ein Ausdruck. Verschachtelte Operatoren brauchen kein $ (dürfen es aber haben).

Im Zweifelsfall stellen Sie jedem Operator ein $ voran. Das ist an jeder Stelle richtig.

// Datenstelle: cat ist ein Feldname des Content Type (keine Verkettungsoperation)
"fields": { "cat": { "en-US": "hello" } }
 
// Berechnung an einer Datenstelle: $ nur an der Grenze, innen unverändert
"fields": { "tier": { "en-US": { "$if": [ { ">=": [ "{ /p/score }", 700 ] }, "gold", "silver" ] } } }
 
// Ausdrucksstelle: unverändert schreiben
"condition": { "and": [ { "<": [ "{ /a/body/risk }", 0.5 ] }, { ">=": [ "{ /b/body/score }", 700 ] } ] }

Wenn ein Feldname mit $ beginnen muss: $$

Muss ein Schlüssel tatsächlich mit $ beginnen (wie $ref oder $schema aus JSON Schema), schreiben Sie $ zweimal. "$$ref" bedeutet den Datenschlüssel $ref. Entfernt wird nur das vorderste $ ($$$ref ergibt $$ref), und das gilt nur für Schlüssel (ein $ innerhalb eines Werts bleibt unverändert).

"body": { "$$ref": "#/components/schemas/Item", "topK": { "$min": [ "{ /payload/fields/k }", 50 ] } }

Zwei Fälle, die abgelehnt werden

Die beiden folgenden Fälle werden nicht stillschweigend anders gedeutet, sondern als Fehler abgelehnt.

  • Steht ein $-Schlüssel zusammen mit anderen Schlüsseln im selben Objekt, ist das ein Fehler. Die Operation muss der einzige Schlüssel dieses Objekts sein; benachbarte Daten ziehen Sie einfach eine Ebene nach außen.
  • Ein unbekannter $-Schlüssel ist ein Fehler. $catt ist kein Feld namens $catt. Der $-Namensraum ist für Operatoren reserviert.

An einer Ausdrucksstelle ist es ebenfalls ein Fehler, wenn ein Operatorname zusammen mit weiteren Schlüsseln steht ({ "and": […], "or": […] }). An dieser Stelle gibt es keine Lesart als Daten und jedes Objekt gilt als wahr. Bliebe es so stehen, wäre die Bedingung still immer wahr.

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

  • Fehlt der Pfad oder ist der Wert leer, wird bei einem einzelnen Pointer null und bei einem gemischten Template ein leerer String verwendet.

Kontextwurzeln: Woher die Werte kommen

Das oberste Segment von { /pointer } ist eines der folgenden sieben.

WurzelInhalt
/payloadDas beim Aufruf übergebene JSON-payload (Eingabe). Beispiel: { /payload/fields/email }
/rawPayloadEnthält dieselbe Eingabe als den Body-String, den der Aufrufer gesendet hat (vor dem Parsen). Beispiel: { /rawPayload }
/headersDie beim Aufruf übergebenen HTTP-Anfrageheader. Die Schlüssel sind kleingeschrieben und pro Name gibt es einen einzelnen Wert. Beispiel: { /headers/authorization }
/nowDer Zeitpunkt, zu dem die Ausführung begonnen hat. { /now/seconds }, { /now/millis }, { /now/iso }
/<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 }. Beispiel: { /error/message }

Die sechs Namen ohne /<name> (payload, rawPayload, headers, now, vars, error) sind reserviert und lassen sich nicht als name eines statement verwenden. Derselbe Name würde diese Wurzel überschreiben, daher wird er beim Speichern abgelehnt (siehe Regeln für Bindungsnamen bei den gemeinsamen Feldern).

/rawPayload: der Body genau wie gesendet

/payload ist der geparste Wert, /rawPayload ist der Originalstring desselben Body. Beide zeigen auf dasselbe, sind aber nicht dasselbe. Macht man aus dem geparsten Wert wieder einen String, werden Leerzeichen, Zahlennotation, Escapes und doppelte Schlüssel alle normalisiert, und man kommt nicht zu den gesendeten Bytes zurück.

Deshalb lässt sich ein Wert, der über den gesendeten Bytes berechnet wird, nur mit /rawPayload behandeln. Der typische Fall ist die Signaturprüfung eines Zahlungsdienstleister-Webhooks (siehe Signature). Für die übliche Referenz, bei der Sie einen Wert herausholen, verwenden Sie /payload.

Der Aufruf-Body nimmt nur ein JSON-Objekt an. Ist der Body leer, gilt er als nicht vorhanden; ist er kein JSON-Objekt (defektes JSON, Array, Skalar, literales null), wird nicht ausgeführt, sondern abgelehnt (siehe Fehler).

/now: der Zeitpunkt des Ausführungsstarts

/now enthält den Zeitpunkt, zu dem diese Ausführung begonnen hat, in drei Formen.

PointerWert
{ /now/seconds }Epoch-Sekunden (Ganzzahl)
{ /now/millis }Epoch-Millisekunden (Ganzzahl)
{ /now/iso }Der Zeit-String in der Notation der Plattform, wie bei sys.createdAt (UTC)
  • Eine Ausführung hat nur einen einzigen Zeitpunkt. Es ist kein statement, das die Uhr liest, sondern ein Wert, der beim Start der Ausführung eingesetzt wird; zwei Statements können also nie unterschiedliche Werte sehen. Auch jeder Branch von Parallel erbt denselben Zeitpunkt. Da es kein statement ist, zählt es auch nicht auf die Anzahl der Statements.
  • Es gibt kein Feld, mit dem man eine Zeitzone wählt. Ein Epoch-Wert ist überall dieselbe Zahl, und iso ist eine UTC-Notation.
  • Verwenden Sie es zur Prüfung des Replay-Window eines Webhooks (wie viele Sekunden der in der Signatur mitgeführte Zeitstempel von jetzt entfernt ist). Der Zeitstempel kommt üblicherweise als String an, wird aber von der arithmetischen Operation in eine Zahl umgewandelt und lässt sich daher unverändert vergleichen.
// liegt der in der Signatur mitgeführte Zeitstempel innerhalb von 5 Minuten (300 Sekunden)
{ "<": [ { "-": [ "{ /now/seconds }", "{ /sig/1 }" ] }, 300 ] }

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 }
ResourceForEach(während der Iteration) name ist das aktuelle Element = die Ressource selbst. Nur innerhalb von onEach referenzierbar{ /post/sys/id }, { /post/fields/title/en-US }
ResourceCountDie Anzahl der Übereinstimmungen (Ganzzahl){ /commentCount }
ParseJsonDer geparste Wert selbst (Objekt, Array, Skalar){ /quote/items/0/price }
SignatureBoolean (ob die Prüfung bestanden wurde){ /verified }
HashString (der Digest in der deklarierten Notation){ /expectedSign }
RegexBei Match ein Boolean. Bei Capture ein Array (0 = der gesamte Treffer, ab 1 die Capture-Gruppen) oder null, wenn es keinen Treffer gibt{ /isOrderId }, { /sig/1 }
  • 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.
  • Liest man einen ServiceUser, ist das Ergebnis die Mitglieder-Ressource selbst ({ /member/sys/id }). Anders als bei Content und Media sind die Felder keine Locale-Map, sondern der Wert unmittelbar. Die Regeln werden unter Mitgliederverzeichnis lesen behandelt.

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.
  • Der Operator muss der einzige Schlüssel des Objekts sein. An einer Datenstelle ist nur ein Schlüssel mit $ eine Operation, an einer Ausdrucksstelle ist es eine Operation mit oder ohne $ (siehe Datenstelle und Ausdrucksstelle).

Operatortabelle

Die Namen in der Tabelle sind die Operator-Token. An einer Datenstelle stellen Sie ihnen ein $ voran (aus cat wird $cat). An einer Ausdrucksstelle geht beides.

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).
Datumdate{ "date": [Wert, Ausgabeeinheit] }. Normalisiert den Wert zu einem vergleichbaren Zeitpunkt. Als Ausgabeeinheit gibt es millis (Standard), seconds, iso und day. Siehe Datumsnormalisierung.

Array-Iterationsoperatoren (map, filter, reduce, all, some, none) werden nicht unterstützt. Script iteriert über Arrays mit Loop (Loop im Statement-Katalog). Auch das Heraussuchen nur derjenigen Einträge einer Liste, die einer Datumsbedingung entsprechen, ist keine Iteration, sondern die Aufgabe der lesenden Statements. Geben Sie die Bedingung im where von ResourceFind und ResourceForEach an, dann filtert der Server und gibt das Ergebnis zurück (die verwendbaren Operatoren stehen in der Operatorliste).

Zahlenkonvertierung und Beispiele

Die Regeln der Zahlenkonvertierung sind wie folgt: Zahlen bleiben unverändert, true wird zu 1, false zu 0, Strings werden geparst (kann der String nicht geparst werden, schlägt die Berechnung fehl) und null wird zu 0 konvertiert.

Datums-Strings sind keine Zahlen. "2026-10-03" lässt sich nicht als Zahl parsen, daher geben Vergleichsoperatoren ohne Fehler immer false zurück. Um Datumswerte zu vergleichen, normalisieren Sie sie zuerst mit date.

Die folgenden Snippets gehen von einer Ausdrucksstelle aus. Wenn Sie sie an eine Datenstelle (fields, Http.body, Return.value, SetVar.value) setzen, stellen Sie dem obersten Operator ein $ voran und lassen die inneren Operanden unverändert.

{ "-":  [ "{ /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 }" ] ] }                       // Array akkumulieren: SetVar.value ist eine Datenstelle, daher $
{ "if": [ "{ /payload/fields/next }", "{ /payload/fields/next }", "END" ] }     // wenn next vorhanden, next, sonst "END"

Datumsnormalisierung (date)

Vergleichsoperatoren wandeln ihre Operanden in Zahlen um und vergleichen erst dann. Ein Datums-String ist keine Zahl, daher ergibt dieser Vergleich ohne Fehler immer false. Ein Wechsel zu == löst das nicht. Sind beide Seiten keine Zahlen, wird der Text unmittelbar verglichen, und damit werden "2026-10-03" und "2026-10-03T00:00:00.000Z", die denselben Zeitpunkt unterschiedlich schreiben, zu zwei verschiedenen Werten. Normalisieren Sie ein Datum vor dem Vergleich mit date.

{ "date": [ Wert, Ausgabeeinheit ] }     // die Ausgabeeinheit kann entfallen
{ "date": "2026-10-03" }          // wird nur ein Wert übergeben, darf das Array entfallen

Eigene Operatoren before, after oder equal gibt es nicht. Der normalisierte Wert ist eine Zahl, daher verwenden Sie die vorhandenen Vergleichs-, Arithmetik- und Aggregationsoperatoren unverändert.

Was geprüft werden sollDer Ausdruck dafür
a liegt vor b{ "<": [ { "date": a }, { "date": b } ] }
a liegt nach b{ ">": [ { "date": a }, { "date": b } ] }
Derselbe Zeitpunkt{ "==": [ { "date": a }, { "date": b } ] }
Derselbe Tag (Uhrzeit ignoriert){ "==": [ { "date": [a, "day"] }, { "date": [b, "day"] } ] }
Zwischen from und to{ "<=": [ { "date": from }, { "date": x }, { "date": to } ] } (verketteter Vergleich)
Eine Woche später{ "date": [ { "+": [ { "date": x }, 604800000 ] }, "iso" ] }
Tagesdifferenz zweier Datumswerte{ "/": [ { "-": [ { "date": a }, { "date": b } ] }, 86400000 ] }
Das früheste unter mehreren Datumswerten{ "min": [ { "date": a }, { "date": b } ] }

Das Ergebnis der Arithmetik ist wieder eine Millisekundenzahl, daher können Sie es noch einmal in date geben und als iso oder day ausgeben (siehe „Eine Woche später“ in der Tabelle oben).

// Ausdrucksstelle: liegt der Coupon innerhalb seiner Gültigkeit. Die drei Werte dürfen unterschiedlich notiert sein
{ "<=": [
  { "date": "{ /coupon/fields/startsAt/en-US }" },
  { "date": "{ /now/iso }" },
  { "date": "{ /coupon/fields/endsAt/en-US }" }
] }
 
// Ausdrucksstelle: liegt der HTTP-Header Date innerhalb von 5 Minuten (300 Sekunden) von jetzt
{ "<": [ { "-": [ "{ /now/seconds }", { "date": [ "{ /headers/date }", "seconds" ] } ] }, 300 ] }

Eingaben, die gelesen werden

Die folgenden Werte werden alle als derselbe Zeitpunkt gelesen.

FormatBeispiel
ISO-8601, RFC 33392026-10-03T00:00:00Z, 2026-10-03T00:00:00.000Z, 2026-10-03T09:00:00+09:00
Zeit ohne Sekunden oder Sekundenbruchteile2026-10-03T00:00
Zeit mit einem Leerzeichen anstelle des T2026-10-03 00:00:00
Nur das Datum (wird als UTC-Mitternacht gelesen)2026-10-03
RFC 1123 (die Notation des HTTP-Headers Date)Sat, 03 Oct 2026 00:00:00 GMT
Epoch-Zahl und Zahlenstring1790985600, 1790985600000, "1790985600"
  • Ohne Offset wird als UTC gelesen. Als Offset werden +09:00, +0900, +09 und Z alle angenommen.
  • Das Parsen ist strikt. Auch bei passender Stellenzahl schlägt ein Datum fehl, das es tatsächlich nicht gibt (2026-13-45).
  • Beim Epoch entscheidet die Größe des Absolutwerts über die Einheit. Unter 100.000.000.000 sind es Sekunden, ab diesem Wert Millisekunden. Daher werden { /now/seconds } und { /now/millis } jeweils richtig gelesen, egal welches der beiden Sie einsetzen.
  • Als Epoch anerkannt wird ein Absolutwert von 100.000.000 bis unter 100.000.000.000.000. Da die Einheit über die Größe entschieden wird, ist der Bereich auf beiden Seiten begrenzt. Andere Zahlen schlagen fehl, statt als Jahr 1970 gelesen zu werden. Dazu gehören das Datum ohne Trennzeichen 20261003, die Jahresangabe 2026 und die 0, die für einen fehlenden Wert übergeben wird.

Ausgabeeinheiten

Der zweite Operand bestimmt die Ausgabeform. Bei den Namen der Einheiten wird Groß- und Kleinschreibung nicht unterschieden.

WertErgebnisVerwendung
Weggelassen, millisEpoch-Millisekunden (Zahl)Vergleich und Arithmetik
secondsEpoch-Sekunden (Zahl). Bruchteile unter einer Sekunde werden verworfenExterne APIs, die Epoch-Sekunden annehmen
iso2026-10-03T00:00:00.000ZSchreiben in ein Date-Feld von Content
day2026-10-03 (nach UTC)Vergleich desselben Tages, Anzeige

Geben Sie einen Namen an, der nicht in der Liste steht, schlägt es fehl, und die Fehlermeldung listet die verwendbaren Namen auf.

iso-Ausgabe und Schreiben in ein Date-Feld

Ein Date-Feld von Content nimmt beim Schreiben nur ein einziges Format an: yyyy-MM-ddTHH:mm:ss[.Bruchteile]Z. Das T, die Sekunden und das Z am Ende müssen alle vorhanden sein, die Sekundenbruchteile dürfen dabei sein oder fehlen, und der Wert wird als UTC gelesen. Tragen Sie ein per payload empfangenes 2026-10-03 oder 2026-10-03T09:00:00+09:00 unverändert ein, wird es deshalb als ungültiger Wert abgelehnt. Da die iso-Ausgabe von date genau dieses Format hat, lassen Sie ein empfangenes Datum vor dem Schreiben in das Feld einmal durch date laufen.

// Datenstelle: das "2026-10-03" aus dem payload wird in das Ablaufdatum des Coupons geschrieben
"fields": { "endsAt": { "en-US": { "$date": [ "{ /payload/fields/endsAt }", "iso" ] } } }

Werte, die nicht gelesen werden können

In den folgenden drei Fällen schlägt das betreffende statement fehl (status 400). Es ist ein Fehler zur Laufzeit und lässt sich daher mit dem catch von Try lokal behandeln.

  • Der erste Operand fehlt, oder die Referenz hat keinen Wert gefunden.
  • Der Wert lässt sich nicht als Datum lesen. Dazu gehören ein leerer String, ein String aus nur Leerzeichen, ein String, der kein Datum ist, ein nicht existierendes Datum, ein Boolean, ein Objekt und eine Zahl außerhalb des anerkannten Bereichs.
  • Der Name der Ausgabeeinheit steht nicht in der Liste.

Dass bei einem fehlenden Wert kein null zurückgegeben wird, ist ein beabsichtigter Vertrag. null wird bei der Zahlenkonvertierung zu 0 und damit gegen das Jahr 1970 verglichen; eine Prüfung ohne Datum schlägt dann nicht fehl, sondern kippt im Ergebnis. Dass ein Coupon außerhalb seiner Gültigkeit durchgelassen wird, ist schlimmer als eine angehaltene Ausführung.

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: 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" }. Was der Ingest tatsächlich tut, wird unter ResourceCreate im Statement-Katalog behandelt.
  • 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 festzulegen, 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

Fehler

Dies sind die Codes, die auftreten, wenn die Regeln für Wertausdrücke verletzt werden. Sie werden beim Speichern geprüft. Die Codes für Verstöße gegen die übrigen statischen Einschränkungen der Definition stehen unter Fehler in Ausführungssemantik, Einschränkungen und Sicherheit, die Codes, die beim Aufrufen auftreten, unter Fehler bei den Endpunkten. Codes, die allen Ressourcen gemeinsam sind, finden Sie unter Gemeinsame Fehler.

CodeBedingung
WGL400056An einer Datenstelle steht ein $-Operationsschlüssel zusammen mit anderen Schlüsseln im selben Objekt.
WGL400055An einer Datenstelle steht ein $-Schlüssel, der nicht als Operator definiert ist.