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
| Form | Regel | Beispiel |
|---|---|---|
| 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.
| Stelle | Betroffene Felder | Wie sie gelesen wird |
|---|---|---|
| Datenstelle | fields (ResourceCreate, ResourceUpdate, ResourcePatch), Http.body, Return.value, SetVar.value, Cache.value, Cache.defaultValue | Ein Schlüssel ohne $ ist immer ein Feldname. Für eine Operation stellen Sie ein $ voran. |
| Ausdrucksstelle | If.condition, Loop.while, version | Der gesamte Wert ist ein Ausdruck. Als Operator geht cat genauso wie $cat. |
| Template-Stelle | Alles Ü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 Literal | Regex.pattern, Cache.key | Es ist kein Wertausdruck. Ein { /pointer }, das in Regex.pattern steht, wird nicht ersetzt, sondern Teil des Patterns. |
Die Regeln passen in zwei Zeilen.
- An einer Datenstelle ist ein Schlüssel ohne
$immer ein Feldname. Für eine Operation stellen Sie dem Operator ein$voran. - 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.$cattist 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
nullund bei einem gemischten Template ein leerer String verwendet.
Kontextwurzeln: Woher die Werte kommen
Das oberste Segment von { /pointer } ist eines der folgenden sieben.
| Wurzel | Inhalt |
|---|---|
/payload | Das beim Aufruf übergebene JSON-payload (Eingabe). Beispiel: { /payload/fields/email } |
/rawPayload | Enthält dieselbe Eingabe als den Body-String, den der Aufrufer gesendet hat (vor dem Parsen). Beispiel: { /rawPayload } |
/headers | Die beim Aufruf übergebenen HTTP-Anfrageheader. Die Schlüssel sind kleingeschrieben und pro Name gibt es einen einzelnen Wert. Beispiel: { /headers/authorization } |
/now | Der 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 } |
/error | Wird 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.
| Pointer | Wert |
|---|---|
{ /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
Parallelerbt 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
isoist 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.
| statement | Ergebnisform | Referenzbeispiel |
|---|---|---|
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 } |
ResourceCount | Die Anzahl der Übereinstimmungen (Ganzzahl) | { /commentCount } |
ParseJson | Der geparste Wert selbst (Objekt, Array, Skalar) | { /quote/items/0/price } |
Signature | Boolean (ob die Prüfung bestanden wurde) | { /verified } |
Hash | String (der Digest in der deklarierten Notation) | { /expectedSign } |
Regex | Bei 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 } |
ResourceFindbindetnull, wenn es keine Übereinstimmung gibt. Mit{ "==": [ "{ /found }", null ] }verzweigt man nach dem Vorhandensein.ResourceRead(einzeln) ist ein Fehler, wenn das Ziel nicht existiert (mitTrybehandelbar). 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 (auscatwird$cat). An einer Ausdrucksstelle geht beides.
| Kategorie | Operator | Bedeutung und Beispiel |
|---|---|---|
| Bedingung | if (Alias ?:) | { "if": [Bedingung, Wahr-Wert, Bedingung2, Wahr-Wert2, …, Standardwert] }. Wert der ersten wahren Bedingung, sonst der letzte Standardwert. |
| Logik | and, or | Kurzschlussauswertung. 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. |
| Aggregation | min, max | Minimum und Maximum der Operanden. |
| String | cat | Verkettet alle Operanden zu einem String. |
| Enthaltensein | in | { "in": [needle, haystack] }. Ist haystack ein String, Teilstring-Prüfung; ist es eine Collection, Element-Enthaltensein. |
| Array | merge | Flacht mehrere Arrays oder Werte zu einem einzigen Array ab (für kumulatives Sammeln). |
| Datum | date | { "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 entfallenEigene 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 soll | Der 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.
| Format | Beispiel |
|---|---|
| ISO-8601, RFC 3339 | 2026-10-03T00:00:00Z, 2026-10-03T00:00:00.000Z, 2026-10-03T09:00:00+09:00 |
| Zeit ohne Sekunden oder Sekundenbruchteile | 2026-10-03T00:00 |
Zeit mit einem Leerzeichen anstelle des T | 2026-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 Zahlenstring | 1790985600, 1790985600000, "1790985600" |
- Ohne Offset wird als UTC gelesen. Als Offset werden
+09:00,+0900,+09undZalle 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 Jahresangabe2026und die0, 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.
| Wert | Ergebnis | Verwendung |
|---|---|---|
Weggelassen, millis | Epoch-Millisekunden (Zahl) | Vergleich und Arithmetik |
seconds | Epoch-Sekunden (Zahl). Bruchteile unter einer Sekunde werden verworfen | Externe APIs, die Epoch-Sekunden annehmen |
iso | 2026-10-03T00:00:00.000Z | Schreiben in ein Date-Feld von Content |
day | 2026-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 Zahl0, 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:falseliegt 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" }
}ResourceCreatemuss für jedes befüllte Feld den Bucket der Standard-Locale des Space enthalten (default-locale-Regel).ResourceUpdateist eine vollständige Ersetzung. Felder und Locales, die nicht infieldsstehen, werden entfernt (einschließlich file).ResourcePatchaktualisiert nur die angegebenen Felder und Buckets (die übrigen Felder und Locales bleiben erhalten).- Löschen mit literalem
null: Ist der Wert literalesnull, 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 literalemnull. Mediafile: 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:falsewird 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
whereundorderwendet die Engine auffields.Xautomatisch 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 LocaleFehler
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.
| Code | Bedingung |
|---|---|
WGL400056 | An einer Datenstelle steht ein $-Operationsschlüssel zusammen mit anderen Schlüsseln im selben Objekt. |
WGL400055 | An einer Datenstelle steht ein $-Schlüssel, der nicht als Operator definiert ist. |
Verwandte Dokumente
- Statement-Katalog: Felder und Ergebnisse der 25 Statement-Typen, die Wertausdrücke verwenden.
- Ausführungssemantik, Einschränkungen und Sicherheit: Ausführungsreihenfolge, Fehler, optimistisches Sperren, statische Einschränkungen.
- Cookbook: Vollständige Beispiele, die Wertausdrücke kombinieren.
- Script-Übersicht: Struktur der obersten Ebene und die Zeit für eine einzelne Ausführung.
