Personalisierungssyntax personalization-syntax

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:

Anwendungsfall
Syntax
Rendern eines Profilattributs
{{profile.person.name.firstName}}
Aufrufen einer PQL-Funktion
{%= upperCase(profile.person.name.firstName) %}
Bedingter Block
{%#if profile.loyalty.tier = "gold"%}...{%/if%}
Durchlaufen eines Arrays
{{#each profile.orders}}...{{/each}}

Die Attributstruktur wird in einem XDM-Schema von Adobe Experience Platform definiert. Weitere Informationen.

TIP
Gebrauchsfertige Ausdrücke, die diese Syntaxen auf reale Szenarien anwenden – Datumsformatierung, Countdowns, bedingte Fallbacks und vieles mehr – finden Sie auf der Seite Personalisierungsrezepte.

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 „&amp;“ generiert. Wenn Sie wünschen, dass Handlebars einen Wert nicht escapen, verwenden Sie drei geschweifte Klammern.

    Angenommen, der Wert des Felds profile.person.name lautet „Mark & Mary“. Die Syntax {{profile.person.name}} zeigt Mark &amp; Mary an, während {{{profile.person.name}}} Mark & Mary anzeigt.

  • 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.

NOTE
Das Maskieren von Backtick-Zeichen gilt sowohl für Handlebars-Pfade ({{...}}) 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 %}
NOTE
Das Maskieren von Backticks wird nur innerhalb von PQL-Ausdrücken ({%= ... %}) 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():

{% let ts = formatDate(toDateTime(context.journey.events.`1697323153`.timestamp), "dd/MM/yyyy") %}
{{ts}}

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:

Szenario
Lösung
Numerischer Wert, der als Zeichenfolge gespeichert wird
Verwenden Sie stringToNumber() vor arithmetischen Operationen oder Vergleichen: {%= stringToNumber(profile.loyalty.pointsBalance) > 500 %}
Ganzzahl gespeichert als Zeichenfolge
Verwenden Sie string_to_integer() oder stringToNumber() vor arithmetischen Operationen
Boolescher Wert gespeichert als Zeichenfolge
Verwenden Sie toBool() 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].Attribute

    Hier gilt:

    • offers identifiziert den Pfadausdruck, der zum Angebots-Namespace gehört.
    • Type bestimmt den Typ der Angebotsdarstellung. Zu den möglichen Werten gehören image, html und text
    • Placement Id und Activity Id sind Platzierungs- und Aktivitätskennungen.
    • Attributes sind angebotsspezifische Attribute, die vom Angebotstyp abhängen. Beispiel: deliveryUrl fü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:

Literal
Definition
Zeichenfolge
Ein Datentyp, der aus Zeichen besteht, die von doppelten Anführungszeichen umgeben sind.
Beispiele: "prospect", "jobs", "articles"
Boolesch
Ein Datentyp, der entweder „true“ oder „false“ ist.
Ganzzahl
Ein Datentyp, der eine ganze Zahl darstellt. Sie kann positiv, negativ oder null sein.
Beispiele: -201, 0, 412
Array
Ein Datentyp, der aus einer Gruppe anderer Literalwerte besteht. Zur Gruppierung werden eckige Klammern und Kommas verwendet, um zwischen verschiedenen Werten zu trennen.
Hinweis: Sie können nicht direkt auf die Eigenschaften von Elementen in einem Array zugreifen.
Beispiele: [1, 4, 7], ["US", "FR"]
CAUTION
Die Variable xEvent ist in Personalisierungsausdrücken nicht verfügbar. Die Verwendung von xEvent führt zu Überprüfungsfehlern.

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.

{%#if profile.loyalty.tier = "gold"%}
Gold member content
{%else if profile.loyalty.tier = "silver"%}
Silver member content
{%else%}
Default content
{%/if%}

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 {%= ... %}:

Inkorrekt
Korrekt
{{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:

{{#each profile.orders as |order|}}
  {%#if order.status = "pending"%}
  Order {{order.id}} is pending.
  {%/if%}
{{/each}}

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:

{% let topOrders = topN(profile.orders, price, 3) %}
{{#each topOrders}}
  {{this.name}} — {{this.price}}&euro;
{{/each}}

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:

{% let cleanName = replaceAll(profile.person.name.firstName, "[^a-zA-Z]", "") %}
Hi {{cleanName}}, your code is: WELCOME-{%= upperCase(cleanName) %}

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:

{% let daysLeft = dateDiff(getCurrentZonedDateTime(), stringToDate(profile.loyalty.expiryDate)) %}

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.

AI Knowledge Reference

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() or toBool(), 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 xEvent variable is not available in personalization expressions; any reference to xEvent results 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 like upperCase() and formatDate(), 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 &amp;); 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.
recommendation-more-help
journey-optimizer-help