Auf dieser Seite: Erfahren Sie mehr über die Handlebars- und PQL-Personalisierungssyntax in Adobe Journey Optimizer, einschließlich allgemeiner Regeln, reservierter Keywords, Typ-Erzwingung, verfügbarer Namespaces und Best Practices.
Die Personalisierung in Journey Optimizer nutzt zwei sich ergänzende Syntaxen, die im selben Ausdruck zusammenarbeiten:
- Handlebars (
{{...}}) – Wird zum Rendern von Profilattributen, zum Durchlaufen von Arrays und zum Aufrufen von Block-Helpern verwendet. Eine vollständige Referenz finden Sie in der Dokumentation zu HandlebarsJS. - Profile Query Language (PQL) (
{%= ... %}) – Wird zum Aufrufen integrierter Funktionen (z. B.upperCase(),formatDate(),dateDiff()) und zum Auswerten bedingter Ausdrücke verwendet.
Um Laufzeitfehler zu vermeiden, ist es von entscheidender Bedeutung zu verstehen, in welchem Kontext Sie sich befinden. Beispielsweise schlägt ein in {{...}} platzierter PQL-Funktionsaufruf fehl, weil Handlebars versucht, ihn als Helper aufzulösen, anstatt ihn als PQL-Ausdruck auszuwerten.
Beispiele:
{{profile.person.name.firstName}}{%= upperCase(profile.person.name.firstName) %}{%#if profile.loyalty.tier = "gold"%}...{%/if%}{{#each profile.orders}}...{{/each}}Die Attributstruktur wird in einem XDM-Schema von Adobe Experience Platform definiert. Weitere Informationen.
Allgemeine Syntaxregeln general-rules
-
Kennungen können beliebige Unicode-Zeichen sein, mit Ausnahme der folgenden Sonderzeichen, die für die Handlebars-Syntax reserviert sind:
code language-none Whitespace ! " # % & ' ( ) * + , . / ; < = > @ [ \ ] ^ ` { | } ~ -
Die Syntax unterscheidet zwischen Groß- und Kleinschreibung.
-
Die Wörter true, false, null und undefined sind nur im ersten Teil eines Pfadausdrucks zulässig.
-
In Handlebars werden den von {{expression}} zurückgegebenen Werten HTML-Escape-Zeichen hinzugefügt. Wenn der Ausdruck „
&“ enthält, wird die Ausgabe mit HTML-Escape-Zeichen als „&“ generiert. Wenn Sie wünschen, dass Handlebars einen Wert nicht escapen, verwenden Sie drei geschweifte Klammern.Angenommen, der Wert des Felds
profile.person.namelautet „Mark & Mary“. Die Syntax{{profile.person.name}}zeigtMark & Maryan, während{{{profile.person.name}}}Mark & Maryanzeigt. -
Bezüglich der Argumente für Literalfunktionen unterstützt der Sprach-Parser für Vorlagen keinen einfachen umgekehrten Schrägstrich ohne Escape-Sequenz (
\). Dieses Zeichen muss mit einem zusätzlichen umgekehrten Schrägstrich (\) mit Escape-Sequenz versehen werden. Beispiel:{%= regexGroup("abc@xyz.com","@(\\w+)", 1)%} -
Um ein Literal in einem Zeichenfolgenwert in doppelte Anführungszeichen einzuschließen (z. B. beim Generieren einer JSON-Ausgabe), maskieren Sie die Anführungszeichen mit einem umgekehrten Schrägstrich (
\"):code language-handlebars { "message": "Hello \"{{profile.person.name.firstName}}\"" }Ausgabe:
{ "message": "Hello \"John\"" }Alternativ können Sie drei geschweifte Klammern
{{{ }}}verwenden, damit HTML nicht maskiert ausgegeben wird, wenn der Wert selbst bestimmte Sonderzeichen enthält, die nicht HTML-codiert werden sollen.
Reservierte Keywords reserved-keywords
Bestimmte Keywords sind in Profile Query Language (PQL) reserviert und können nicht direkt als Feld- oder Variablennamen in Personalisierungsausdrücken verwendet werden. Wenn Ihr XDM-Schema Felder mit Namen enthält, die reservierten Keywords entsprechen, müssen Sie diese mit Backticks (`) maskieren, wenn Sie in Ihren Ausdrücken darauf verweisen möchten.
Zu den reservierten Keywords zählen:
- Allgemein:
let,export,to,as,this,last,next,now,NOW,today,yesterday,tomorrow,from,FROM,From,before,BEFORE,Before,after,AFTER,After, - Zeiteinheiten:
millisecond,milliseconds,second,seconds,minute,minutes,hour,hours,day,days,week,weeks,months,year,month,years,decade,decades,century,millennium,centuries,millennia, - Boolesche und logische Operatoren:
true,TRUE,True,false,FALSE,False,not,NOT,Not,and,AND,And,or,Or,OR,null,NULL,Null
Beispiel:
Wenn Ihr Profilschema ein Feld mit dem Namen next enthält, müssen Sie es in Backticks einschließen:
{{profile.person.`next`.name}}
Ohne die Backticks gibt die Validierung des Personalisierungseditors einen Fehler zurück.
{{...}}) als auch für PQL-Ausdrücke ({%= ... %}), da diese Keywords auf der Pfadauflösungsebene reserviert sind. Dies unterscheidet sich von den Feldnamen mit Bindestrich, bei denen das Maskieren von Backtick-Zeichen nur innerhalb von PQL-Ausdrücken unterstützt wird. Siehe Attributschlüssel mit Trennzeichen.PQL-Syntaxregeln für spezielle Attributschlüssel pql-special-keys
Neben reservierten Keywords erfordern zwei zusätzliche Fälle das Maskieren von Backtick-Zeichen in PQL-Ausdrücken.
Attributschlüssel mit Trennzeichen hyphenated-keys
Wenn Ihr XDM-Schema Feldnamen mit Bindestrichen (z. B. my-field, event-type) oder Namen enthält, die mit Zahlen beginnen oder Zahlen enthalten, schließen Sie den Schlüssel in Backticks innerhalb von PQL-Ausdrücken ein:
{%= profile.events.`order-total` > 100 %}
{%= ... %}) unterstützt. Es wird in der Handlebars-Interpolation ({{...}}) nicht unterstützt. Feldnamen mit Bindestrichen können direkt in {{...}}-Blöcken referenziert werden (z. B. {{profile.my-custom-field}}); nur die Backtick-Syntax schlägt dort fehl.Ohne Backticks in einem PQL-Ausdruck wird der Bindestrich als Subtraktionsoperator interpretiert und verursacht einen PQL-Syntaxfehler.
Numerische Ereignis-IDs in Kontextattributen numeric-event-ids
Wenn Sie auf Kontextereignisattribute verweisen, bei denen die Ereignis-ID eine Zahl ist (z. B. 1697323153), schließen Sie sie in Backticks ein. Dies gilt auch innerhalb von Funktionen wie formatDate():
Typ-Erzwingung type-coercion
PQL ist strikt typisiert. Beim Vergleichen oder Übergeben von Werten müssen beide Seiten vom gleichen Typ sein. Häufige Fälle:
stringToNumber() vor arithmetischen Operationen oder Vergleichen: {%= stringToNumber(profile.loyalty.pointsBalance) > 500 %}string_to_integer() oder stringToNumber() vor arithmetischen OperationentoBool() zum Konvertieren: {%= toBool(profile.consents.email.val) = true %}Verfügbare Namespaces namespaces
-
Profil
Dieser Namespace erlaubt die Referenzierung aller im Profilschema definierten Attribute, die unter Dokumentation zum Datenmodell (XDM) von Adobe Experience Platform beschrieben werden.
Die Attribute müssen im Schema definiert sein, damit sie in einem Personalisierungsblock in Journey Optimizer referenziert werden können.
Weitere Informationen zur Verwendung von Profilattributen in Bedingungen finden Sie in diesem Abschnitt.
accordion Beispielverweise {{profile.person.name.fullName}}{{profile.person.name.firstName}}{{profile.person.gender}}{{profile.personalEmail.address}}{{profile.mobilePhone.number}}{{profile.homeAddress.city}}{{profile.faxPhone.number}}
-
Zielgruppe
Weitere Informationen zum Segmentierungs-Service finden Sie in dieser Dokumentation.
-
Angebote
In diesem Namespace können Sie bestehende Entscheidungen referenzieren.
Um ein Angebot zu referenzieren, müssen Sie einen Pfad mit den verschiedenen Informationen angeben, die das Angebot definieren. Dieser Pfad weist die folgende Struktur auf:
offers.Type.[Placement Id].[Activity Id].AttributeHier gilt:
offersidentifiziert den Pfadausdruck, der zum Angebots-Namespace gehört.Typebestimmt den Typ der Angebotsdarstellung. Zu den möglichen Werten gehörenimage,htmlundtextPlacement IdundActivity Idsind Platzierungs- und Aktivitätskennungen.Attributessind angebotsspezifische Attribute, die vom Angebotstyp abhängen. Beispiel:deliveryUrlfür Bilder
Weitere Informationen zur Entscheidungs-API und zu Angebotsdarstellungen finden Sie auf dieser Seite.
Ein Validierungsmechanismus, der auf dieser Seite beschrieben wird, validiert alle Verweise anhand des Angebotsschemas.
accordion Beispielverweise -
Speicherort, an dem das Bild gehostet wird:
offers.image.[offers:xcore:offer-placement:126f767d74b0da80].[xcore:offer-activity:125e2c6889798fd9].deliveryUrl -
Ziel-URL beim Klicken auf das Bild:
offers.image.[offers:xcore:offer-placement:126f767d74b0da80].[xcore:offer-activity:125e2c6889798fd9].linkUrl -
Text-Inhalt des Angebots aus der Entscheidungs-Engine:
offers.text.[offers:xcore:offer-placement:126f767d74b0da80].[xcore:offer-activity:125e2c6889798fd9].content -
HTML-Inhalt des Angebots aus der Entscheidungs-Engine:
offers.html.[offers:xcore:offer-placement:126f767d74b0da80].[xcore:offer-activity:125e2c6889798fd9].content
Helper helpers-all
Ein Handlebars-Helper ist eine einfache Kennung, auf die Parameter folgen können. Jeder Parameter ist ein Handlebars-Ausdruck. Helper können in jedem Kontext einer Vorlage aufgerufen werden.
Diese Block-Helper werden durch ein # am Anfang des Helper-Namens gekennzeichnet und erfordern einen passenden schließenden / am Ende des Namens.
Blöcke sind Ausdrücke mit einer Blockeröffnung ({{# }}) und schließendem ({{/}}).
Weitere Informationen zu Helper-Funktionen finden Sie in diesem Abschnitt.
Literaltypen literal-types
Adobe Journey Optimizer unterstützt die folgenden Literaltypen:
Beispiele:
"prospect", "jobs", "articles"Beispiele:
-201, 0, 412Hinweis: Sie können nicht direkt auf die Eigenschaften von Elementen in einem Array zugreifen.
Beispiele:
[1, 4, 7], ["US", "FR"]Best Practices best-practices
Überprüfen Sie diese Syntaxregeln, bevor Sie Personalisierungsausdrücke erstellen. Die meisten Laufzeitfehler rühren aus der Vermischung von Handlebars- und PQL-Kontexten her.
Verwenden der richtigen Syntax für bedingte Blöcke
Verwenden Sie immer {%#if%} / {%else if%} / {%else%} / {%/if%}. Die Syntax {% if %} / {% elseif %} / {% endif %} wird nicht unterstützt.
Rufen Sie keine PQL-Funktionen in Handlebars-Blöcken ({{...}}) auf
{{...}} löst nur Handlebars-Variablen und -Helper auf – PQL wird nicht ausgewertet. Das Einschließen einer PQL-Funktion wie upperCase() innerhalb von {{...}} führt zu einem Fehler des Typs „Helper nicht gefunden“. Verwenden Sie stattdessen {%= ... %}:
{{upperCase(cleanName)}}{%= upperCase(cleanName) %}Verwenden eines Alias für eine benannte Schleife beim Kombinieren von {{#each}} mit{%#if%}
this.field wird vom Handlebars-Renderer aufgelöst, jedoch nicht vom PQL-Auswerter innerhalb einer {%#if%}-Bedingung. Definieren Sie einen benannten Alias mit as |item|, damit beide Kontexte das Feld auflösen können:
Zuweisen der Ergebnisse der PQL-Funktion zu einer Variablen vor der Schleife
PQL-UDFs wie topN können nicht direkt in {{#each}} aufgerufen werden. Werten Sie sie zunächst mit {% let %} aus und iterieren Sie dann über das Ergebnis:
Verwenden von {% let %}, um die Wiederholung von Funktionsaufrufen zu vermeiden
Wenn ein berechneter Wert mehrmals benötigt wird, speichern Sie ihn in einer Variablen. Dies verbessert die Lesbarkeit und verhindert redundante Auswertungen:
Verwenden der richtigen Argumentreihenfolge fürdateDiff
dateDiff(start, end) nimmt das frühere Datum zuerst. Um die bis zu einem zukünftigen Datum verbleibenden Tage zu berechnen, übergeben Sie das aktuelle Datum als erstes Argument:
Verwenden von = für Gleichheitsvergleiche in PQL, nicht==
PQL verwendet für die Gleichheit einen einzelnen =-Operator. Die Verwendung von == führt zu einem Syntaxfehler.
Verwenden von Backticks für Feldnamen mit Bindestrichen – nur in PQL-Ausdrücken
Wenn ein XDM-Schemafeldname einen Bindestrich enthält (z. B. order-total), schließen Sie ihn in Backticks ein, um zu verhindern, dass der Bindestrich als Subtraktionsoperator geparst wird. Dies wird nur innerhalb PQL-Ausdrücken ({%= ... %}) unterstützt, nicht in Handlebars-Blöcken ({{...}}):
{%= profile.events.`order-total` > 100 %}
Gebrauchsfertige Ausdrücke, die Sie direkt in Ihren Inhalt kopieren können, finden Sie unter Personalisierungsrezepte.
This section contains structured knowledge intended to support interpretation, retrieval, and question answering related to this topic.
For complete understanding, this information should be combined with the documentation on this page. Neither source is intended to stand alone; the page describes the feature, while this section provides additional context that helps disambiguate terminology, intent, applicability, and constraints.
- TL;DR: This page explains the Handlebars and PQL personalization syntaxes in Journey Optimizer — their general rules, reserved keywords, namespace structure, type system, and best practices for avoiding common runtime errors.
Intents:
- Understand when to use Handlebars (
{{...}}) vs. PQL ({%= ... %}) syntax - Apply general syntax rules: reserved characters, case sensitivity, HTML escaping, backslash handling
- Escape reserved keywords and special attribute keys (hyphenated names, numeric event IDs) correctly
- Apply type coercion when comparing or passing values of mismatched types
- Reference personalization from the available namespaces: Profile, Audience, Offers
- Follow best practices to avoid the most common runtime and validation errors
Glossary:
- Handlebars: The
{{...}}templating syntax used for rendering attributes, looping over arrays, and calling block helpers; HTML-escapes output by default. (product-specific) - Profile Query Language (PQL): The
{%= ... %}expression syntax used for calling built-in functions (e.g.upperCase(),formatDate()) and evaluating conditional expressions. (product-specific) - Triple-stash (
{{{ }}}): A Handlebars syntax variant that outputs values without HTML escaping, useful when the value itself contains HTML characters that should not be encoded. - Reserved keywords: PQL identifiers that cannot be used directly as field or variable names, grouped as general keywords (
let,export,to,as,this,last,next,now,NOW,today,yesterday,tomorrow,from,FROM,From,before,BEFORE,Before,after,AFTER,After), time units (millisecond,milliseconds,second,seconds,minute,minutes,hour,hours,day,days,week,weeks,month,months,year,years,decade,decades,century,centuries,millennium,millennia), and boolean/logical operators (true,TRUE,True,false,FALSE,False,not,NOT,Not,and,AND,And,or,OR,Or,null,NULL,Null); must be wrapped in backticks when a schema field uses one of these names. - Type coercion: The explicit conversion of a value from one data type to another (e.g. string → number) using functions like
stringToNumber()ortoBool(), required before comparison or arithmetic in PQL. - Namespace: The top-level grouping of personalization data — Profile, Audience, Offers — each with its own path structure and access rules.
- Block helper: A Handlebars helper identified by
#before the helper name and a matching closing/, used for block constructs like{{#each}}.
Guardrails:
- The
xEventvariable is not available in personalization expressions; any reference toxEventresults in validation failures. - PQL function calls inside
{{...}}Handlebars blocks will fail; use{%= ... %}instead. - The
{% if %}/{% elseif %}/{% endif %}conditional syntax is not supported; use{%#if%}/{%else if%}/{%/if%}. - Backtick escaping for hyphenated field names is only supported inside PQL expressions (
{%= ... %}). In{{...}}Handlebars interpolation, backtick syntax fails — but hyphenated field names can still be referenced directly (e.g.{{profile.my-custom-field}}). - Reserved keywords (general, time-unit, and boolean/logical, e.g.
next,last,this,day,year,true,and,or) must be wrapped in backticks when used as schema field names; applies to both{{...}}and{%= ... %}. - Single backslash
\is not supported as a literal function argument; use double backslash\\. - PQL is strongly typed; mismatched types in comparisons or arithmetic require explicit conversion using
stringToNumber(),toBool(), or similar coercion functions.
Terminology:
- Canonical name: Handlebars — for the
{{...}}syntax; PQL — for the{%= ... %}syntax - Do not confuse:
{{...}}(Handlebars — renders variables and helpers, HTML-escaped) ≠{%= ... %}(PQL — evaluates functions and expressions) ≠{%#if%}/{%/if%}(conditional block syntax, percent-curly braces) - Do not confuse:
{{profile.person.name}}(single-stash — HTML-escaped output) ≠{{{profile.person.name}}}(triple-stash — unescaped output) - Do not confuse: reserved keyword backtick escaping (applies to both
{{...}}and{%= ... %}) ≠ hyphenated key backtick escaping (only supported inside{%= ... %}PQL expressions, not in{{...}}) - Do not confuse:
=(PQL equality operator — correct) ≠==(not valid PQL — causes a syntax error)
FAQ:
- Q: When should I use
{{...}}vs.{%= ... %}? — Use{{...}}(Handlebars) to render attribute values, loop over arrays, and call block helpers. Use{%= ... %}(PQL) to call built-in functions likeupperCase()andformatDate(), and to evaluate conditional expressions. - Q: How do I output a value without HTML encoding? — Use the triple-stash
{{{ }}}instead of{{...}}. Single-brace Handlebars HTML-escapes output (e.g.,&becomes&); triple-stash bypasses escaping. - Q: What is the correct equality operator in PQL? — Use a single
=for equality comparisons in PQL. Using==is a syntax error. - Q: How do I reference a schema field whose name is a reserved keyword (e.g.
next,last,this)? — Wrap it in backticks:{{profile.person.\next`.name}}`. This applies to both Handlebars paths and PQL expressions. - Q: Can I call PQL functions inside
{{...}}Handlebars blocks? — No.{{...}}resolves Handlebars variables and helpers only. A PQL function inside{{...}}causes a “could not find helper” error. Use{%= functionName(...) %}instead.