Deutsch
Merge-Tags
Merge-Tags sind Tokens für dynamische Inhalte -- zum Beispiel den Namen eines Empfängers, einen Produktpreis oder eine Abmelde-URL. Sie erscheinen als hervorgehobene Tokens im Editor und werden unverändert im gerenderten MJML durchgereicht. Ihre E-Mail-Versandplattform ersetzt sie beim Versand durch echte Werte.
Templatical bietet integrierte Syntax-Presets für beliebte Plattformen und unterstützt benutzerdefinierte Syntaxdefinitionen.
Konfiguration
Übergeben Sie ein tags-Array, um Ihre Merge-Tags beim Editor zu registrieren. Wenn der Editor einen Merge-Tag-Wert im Inhalt erkennt (z. B. {{first_name}}), ersetzt er ihn visuell durch das menschenlesbare label ("First Name") — was das Template viel einfacher lesbar und bearbeitbar macht. Der Rohwert bleibt in der Ausgabe erhalten.

Beim Hovern über ein Tag wird der Rohwert hinter dem Label angezeigt.
Die Eigenschaft syntax ist optional und standardmäßig 'liquid'.
ts
import { init } from '@templatical/editor';
const editor = await init({
container: '#editor',
mergeTags: {
tags: [
{ label: 'First Name', value: '{{first_name}}' },
{ label: 'Last Name', value: '{{last_name}}' },
{ label: 'Email', value: '{{email}}' },
{ label: 'Company', value: '{{company.name}}' },
{ label: 'Unsubscribe URL', value: '{{unsubscribe_url}}' },
],
},
});MergeTag-Typ
Jedes Tag wird mit einem Label (in der Editor-Oberfläche angezeigt) und einem Wert (der vollständige Merge-Tag-String einschließlich Trennzeichen) definiert. Zwei optionale Felder — group und description — werden vom integrierten Picker zur Gruppierung und Erklärung verwendet:
ts
interface MergeTag {
label: string;
value: string;
group?: string; // optionale Gruppierung im Picker
description?: string; // optionaler Hilfetext im Picker
sample?: string; // optionaler Beispielwert für Vorschauen
}Der value muss die Syntax-Trennzeichen enthalten. Zum Beispiel mit Liquid-Syntax:
value: '{{first_name}}'
Die Felder group und description sind ausschließlich für den Picker — sie erscheinen weder im Editor-Canvas, noch in der Autovervollständigung, noch in der gerenderten MJML-Ausgabe. Sie werden ignoriert, wenn Sie nur onRequest für die Tag-Auswahl verwenden.
Beispielwerte
Ein Tag kann ein sample tragen — einen Beispielwert, den Vorschauflächen an seiner Stelle anzeigen, sodass eine Vorschau wie eine zugestellte E-Mail liest statt wie eine Liste von Feldnamen:
ts
mergeTags: {
tags: [
{ label: 'Vorname', value: '{{first_name}}', sample: 'Ada' },
{ label: 'Tarif', value: '{{plan_name}}', sample: 'Pro' },
],
}sample zu setzen ist die vollständige Aktivierung — es gibt keinen zusätzlichen Schalter. Der Wert verlässt die Vorschau nie: er wird nicht in die Vorlage geschrieben, nicht von getContent() zurückgegeben, nicht versendet und erscheint nicht in der MJML-Ausgabe. Er wird außerdem im integrierten Picker angezeigt, sodass Autoren vor dem Einfügen sehen, was ein Tag darstellen wird.
Wie Vorschauen ihn verwenden — der Umschalter Beispiel / Bezeichnung, welche Tags ihre Hervorhebung behalten und was im Bearbeitungs-Canvas passiert — ist unter Vorschau-Rendering beschrieben. Diese Seite dokumentiert auch resolvePreview, den Hook, mit dem Ihr eigenes Backend eine Vorschau auflöst — der einzige Weg, Logik-Tags auszuwerten.
Syntax-Presets
Templatical enthält vier integrierte Syntax-Presets. Die Einstellung syntax teilt dem Editor mit, wie sowohl Daten-Tags als auch Logik-Tags im Inhalt erkannt und hervorgehoben werden sollen.
Jedes Preset definiert zwei Muster:
- Daten-Tags -- Variable Merge-Tags wie der Name oder die E-Mail eines Empfängers
- Logik-Tags -- Kontrollflussanweisungen wie Bedingungen und Schleifen
| Preset | Daten-Tag | Logik-Tag | Plattform |
|---|---|---|---|
'liquid' | {{first_name}} | {% if vip %} | Shopify, Jekyll, Django, Jinja2 |
'handlebars' | {{first_name}} | {{#if vip}} | Handlebars.js, Mandrill |
'mailchimp' | *|FIRST_NAME|* | *|IF:VIP|* | Mailchimp |
'ampscript' | %%=first_name=%% | %%[IF @vip]%% | Salesforce Marketing Cloud |
ts
mergeTags: {
syntax: 'handlebars',
tags: [
{ label: 'First Name', value: '{{first_name}}' },
],
}Hervorhebung von Logik-Tags
Neben Daten-Tags erkennt der Editor auch Logik-Tags -- bedingte Anweisungen, Schleifen und andere Kontrollflusssyntax, die von Ihrer E-Mail-Plattform verwendet wird. Diese werden automatisch mit dem logic-Regex-Muster aus dem ausgewählten Syntax-Preset erkannt.
Wenn ein Logik-Tag im Inhalt erkannt wird, extrahiert der Editor das Schlüsselwort (die erste Erfassungsgruppe aus der Logik-Regex) und zeigt es als Großbuchstaben-Abzeichen an -- zum Beispiel wird {% if customer.vip %} als IF gerendert und {% endif %} als ENDIF. Beim Hovern über das Abzeichen wird der vollständige Tag-Wert als Tooltip angezeigt. Benutzer können auf das Abzeichen klicken, um den Rohwert zu bearbeiten.

Logik-Tags werden anders formatiert als Daten-Tags (umrahmtes Abzeichen mit Primärfarbe vs. gefüllter Hintergrund), sodass Template-Autoren auf einen Blick zwischen Daten-Tags und Kontrollfluss unterscheiden können.
Wie Daten-Tags werden Logik-Tags unverändert im gerenderten MJML durchgereicht — Ihre Versandplattform wertet sie zum Versandzeitpunkt aus.
Logik-Tags einfügen
Dieser Abschnitt behandelt die Hervorhebung — jedes Logik-Tag, das Sie tippen oder einfügen, wird automatisch erkannt. Um Benutzern das Einfügen von Logik-Tags ohne Tippen zu ermöglichen (eine eigene Schaltfläche Logik, Bedingungs-/Schleifenblöcke, die eine Auswahl umschließen), siehe den separaten Leitfaden Logik-Tags. Logik wird unabhängig von Merge-Tags konfiguriert.
Beispiele für Logik-Tags nach Preset:
html
{% if customer.vip %}
<p>Exclusive offer just for you!</p>
{% endif %}
{% for item in cart.items %}
<p>{{item.name}} - {{item.price}}</p>
{% endfor %}html
{{#if hasSubscription}}
<p>Your plan renews on {{renewal_date}}</p>
{{/if}}
{{#each products}}
<p>{{this.name}}</p>
{{/each}}html
*|IF:VIP|*
<p>VIP discount applied</p>
*|END:IF|*html
%%[IF @subscriber_type == "premium"]%%
<p>Premium content here</p>
%%[ENDIF]%%Benutzerdefinierte Syntax
Wenn die integrierten Presets nicht zu Ihrer Plattform passen, definieren Sie eine benutzerdefinierte Syntax mit zwei Regex-Mustern -- eines für Daten-Tags und eines für Logik-Tags:
ts
interface SyntaxPreset {
value: RegExp; // matches data tags like ${user.name}
logic: RegExp; // matches logic tags like $[IF ...]
}Beispiel für eine ${...} / $[...]-Syntax:
ts
mergeTags: {
syntax: {
value: /\$\{.+?\}/g,
logic: /\$\[\s*(\w+).*?\]/g,
},
tags: [
{ label: 'User Name', value: '${user.name}' },
{ label: 'Order Total', value: '${order.total}' },
],
}Die value-Regex erkennt Daten-Tags. Die logic-Regex erkennt Kontrollflussanweisungen — die erste Erfassungsgruppe (\w+) extrahiert das Schlüsselwort (z. B. IF, FOR), das der Editor als Anzeigelabel verwendet.
Autovervollständigung
Wenn Benutzer den Syntax-Öffner (z. B. {{ für Liquid/Handlebars, *| für Mailchimp, %%= für AMPscript) eingeben, zeigt der Editor ein Popup mit übereinstimmenden Tags aus dem konfigurierten tags-Array an. Das Auswählen eines Eintrags (Mausklick, Enter oder Tab) fügt es als Merge-Tag ein — dieselbe Form, die der Toolbar-Picker erzeugt. Esc oder ein Klick außerhalb schließt das Popup.
Die Autovervollständigung funktioniert sowohl in Titel- und Absatz-Rich-Text-Blöcken als auch in jedem Eingabe- und Textbereichsfeld mit Merge-Tag-Unterstützung (Schaltflächen- und Bild-URLs, Bild-Alt-Text, Video- und Menü-Links, das URL-Feld des Rich-Text-Link-Dialogs, Template-Einstellungen und Textfelder benutzerdefinierter Blöcke). Popup, Filterung, Tastaturnavigation und Positionierung sind auf beiden Oberflächen identisch.
Die Filterung ist nicht groß-/kleinschreibungsabhängig und gleicht sowohl label als auch value ab. Die Liste ist auf 10 Ergebnisse begrenzt.
Die Autovervollständigung ist standardmäßig aktiviert. Sie wird automatisch deaktiviert, wenn:
tagsleer ist (keine Kandidaten zum Vorschlagen) odersyntaxeine benutzerdefinierte Regex ist (der Editor kann aus beliebigen Regex-Mustern keine Trigger-Zeichenkette ableiten).
Um sie explizit zu deaktivieren, setzen Sie autocomplete: false:
ts
const editor = await init({
container: '#editor',
mergeTags: {
autocomplete: false,
tags: [
{ label: 'Vorname', value: '{{first_name}}' },
],
},
});Die Schaltfläche Merge-Tag in der Symbolleiste funktioniert weiterhin unabhängig von der Autovervollständigungs-Einstellung.
Integrierter Picker
Wenn Sie mergeTags.tags ohne onRequest-Callback konfigurieren, öffnet ein Klick auf die Schaltfläche Merge-Tag in der Rich-Text-Symbolleiste (oder neben einem Texteingabefeld in der Seitenleiste) ein integriertes modales Picker-Fenster. Der Picker listet jedes Tag aus tags auf, unterstützt Tastaturnavigation und bietet ein Suchfeld, das gegen label, value und description filtert.

Der Picker zeigt:
- das Label (fett)
- den rohen Wert (Monospace, gedimmt)
- die optionale Beschreibung (klein, gedimmt), sofern gesetzt
Wenn mindestens ein Tag ein group-Feld trägt, rendert der Picker sektionierte Überschriften in Einfügereihenfolge (der Reihenfolge in Ihrem tags-Array). Tags ohne group landen unter einer lokalisierten „Sonstige"-Überschrift. Wenn kein Tag eine group hat, rendert der Picker eine flache Liste — keine Überschriften, kein „Sonstige"-Eimer.
Während Sie tippen, werden Gruppen aufgelöst und die Liste gefiltert. Die Filterung ist nicht groß-/kleinschreibungsabhängig und gleicht Teilzeichenketten in label, value oder description ab. Beim Löschen der Suche wird das gruppierte (oder flache) Layout wiederhergestellt.
Ein-Schritt-Einfügen: Ein Klick auf eine Zeile oder das Drücken von Enter auf der hervorgehobenen Zeile fügt das Tag ein und schließt das Modal. Esc, das Schließen-Symbol im Header (×) oder ein Klick auf den Hintergrund schließen den Picker ohne Einfügen.
ts
const editor = await init({
container: '#editor',
mergeTags: {
tags: [
{
label: 'Vorname',
value: '{{first_name}}',
group: 'Empfänger',
description: 'Persönliche Anrede',
},
{
label: 'Nachname',
value: '{{last_name}}',
group: 'Empfänger'
},
{
label: 'Unternehmen',
value: '{{company.name}}',
group: 'Konto'
},
{
label: 'Abmelde-URL',
value: '{{unsubscribe_url}}',
description: 'Gesetzlich vorgeschrieben (Anti-Spam)',
},
],
},
});Dynamisches Tag-Laden
Für große oder kontextabhängige Tag-Listen verwenden Sie den onRequest-Callback anstelle von (oder zusätzlich zu) einem statischen tags-Array. Der Editor ruft diese Funktion auf, wenn der Benutzer klickt, um ein Merge-Tag einzufügen. Verwenden Sie sie, um ein benutzerdefiniertes Picker-Modal zu öffnen, verfügbare Merge-Tags von Ihrer API abzurufen oder eine kontextbezogene Tag-Liste basierend auf dem aktuellen Benutzer zu erstellen. Geben Sie das ausgewählte MergeTag oder null zurück, um abzubrechen.
ts
const editor = await init({
container: '#editor',
mergeTags: {
onRequest: async () => {
const tag = await showMyMergeTagPicker();
return tag; // MergeTag or null if cancelled
},
},
});Vorrangregel
Wenn Sie sowohl tags als auch onRequest angeben, hat onRequest Vorrang — die Schaltfläche Merge-Tag ruft immer Ihren Callback auf. Das statische tags-Array versorgt weiterhin die Autovervollständigungs-Vorschläge beim Tippen.
Ein bereits vorhandenes Tag ändern
Wird ein Tag im Inhalt aktiviert — per Klick oder mit Enter —, öffnet sich erneut die Auswahl, damit der Autor ein anderes Tag wählt. Es ist dieselbe Auswahl wie beim Einfügen, aufgerufen mit einem context, der angibt, worum es geht:
ts
const editor = await init({
container: '#editor',
mergeTags: {
onRequest: async (context) => {
// context: { reason: 'insert' | 'edit', current?: MergeTag }
return showMyMergeTagPicker({ preselect: context?.current });
},
},
});Der Parameter ist optional — ein Callback, der ihn ignoriert, funktioniert unverändert weiter.
Welchen Weg ein aktiviertes Tag nimmt, hängt davon ab, was seinen Token auflösen kann:
| Konfiguration | Beim Aktivieren eines Tags öffnet sich |
|---|---|
onRequest ist gesetzt | immer Ihre Auswahl — context.current enthält das aufgelöste Tag oder fehlt bei einem Token, der keinem Eintrag in tags entspricht |
nur tags ist gesetzt und der Token entspricht einem Eintrag | der integrierte Picker, mit diesem Tag vorausgewählt |
| der Token entspricht nichts, oder keines von beiden ist konfiguriert | ein Texteingabefeld mit dem rohen Token |
Die letzte Zeile ist die einzige Stelle, an der ein Token als Text bearbeitbar ist; sie existiert, damit ein veralteter oder vertippter Token repariert werden kann. Die Eingabe wird dort gegen Ihre syntax geprüft — ein Wert, der kein Merge-Tag ist, wird nie übernommen, da er sonst unverändert in die versendete E-Mail geschrieben würde.
Den rohen Token verbergen
Der Tooltip eines Tags zeigt den Token hinter seinem Label. Das passt zu einer lesbaren Syntax wie {{first_name}}, bei der der Token dem Autor verrät, um welches Feld es sich handelt. Wenn value eine interne Kennung ist, die Ihr Backend auflöst, setzen Sie showRawValue: false:
ts
const editor = await init({
container: '#editor',
mergeTags: {
showRawValue: false,
onRequest: async () => showMyFieldPicker(),
},
});Autoren sehen dann nur noch Labels — im Canvas, in den Feldern der Seitenleiste und im integrierten Picker. Rein visuell: Der Token bleibt im gespeicherten Inhalt und in der gerenderten Ausgabe unverändert.
Die Option bestimmt außerdem, wie ein Tag dargestellt wird, nicht nur seinen Tooltip. Ein Tag ermittelt sein Anzeige-Label in dieser Reihenfolge:
- das
labeldes passenden Eintrags intags; - das Label, das beim Einfügen oder bei der letzten Änderung auf dem Tag gespeichert wurde;
- der Token selbst — oder, mit
showRawValue: false, ein neutraler Platzhalter.
Schritt 2 hält ein Tag lesbar, das Ihr onRequest neu erzeugt hat: Es steht in keinem tags-Array, sodass nur das von Ihnen zurückgegebene Label es identifiziert. Bei einem Tag, das der Editor selbst erzeugt hat — getippt, eingefügt oder aus geladenem Inhalt konvertiert —, ist das gespeicherte Label der Token, sodass beide Schritte übereinstimmen und sich nichts ändert.
Felder in der Seitenleiste
Ein Feldwert ist eine einzelne Zeichenkette, die Text und Token mischt (Hallo {{first_name}}, willkommen). Seine Tags sind einzeln anklickbar und werden wie alle anderen neu ausgewählt. Um den umgebenden Text zu ändern, verwenden Sie Als Text bearbeiten — oder klicken Sie an eine beliebige andere Stelle im Feld —, was die gesamte Zeichenkette öffnet, Token eingeschlossen. showRawValue ändert daran nichts.
Die Tag-Liste nach init() ändern
editor.setMergeTags(tags) ersetzt die konfigurierte Liste zur Laufzeit:
ts
const editor = await init({
container: '#editor',
mergeTags: { tags: initialTags },
});
// Ein Tag wurde umbenannt, oder Ihr Picker hat ein neues erzeugt.
editor.setMergeTags(nextTags);Alles, was ein Tag darstellt, liest dieselbe Liste — Canvas, Felder der Seitenleiste und der integrierte Picker werden gemeinsam neu gezeichnet. Auch unter initCloud() verfügbar.
Das Array zu mutieren funktioniert nicht
In das an init() übergebene Array zu schreiben wird nicht unterstützt. Es zeichnet nichts neu, was bereits auf dem Bildschirm steht — nur Tags, die nach dem Schreibvorgang dargestellt werden, übernehmen die Änderung. Verwenden Sie stattdessen setMergeTags.
Eine Einschränkung bei der Autovervollständigung
Ob die Autovervollständigung aktiv ist, wird entschieden, wenn ein Block zur Bearbeitung geöffnet wird. Von keinen Tags zu einigen zu wechseln aktiviert sie für den nächsten geöffneten Block, nicht für einen bereits in Bearbeitung befindlichen. Alles andere — Labels, die Schaltfläche Merge-Tag, der Picker — aktualisiert sich sofort.
Tokens in geladenen Inhalten
Inhalt, der nie die Eingabeverarbeitung des Editors durchlaufen hat — eine Vorlage aus Ihrem eigenen Speicher oder eine von den @templatical/import-*-Konvertern erzeugte — trägt Merge-Tags als reine {{tokens}} statt als Tag-Knoten. Der Editor wandelt sie beim Hereinkommen um, sodass sich ein geladenes Tag exakt wie ein getipptes verhält: lesbares Label, Hervorhebung, sample und als eine Einheit auswählbar.
Sie müssen nichts aufrufen und nichts aktivieren. Das geschieht überall dort, wo Inhalt eintrifft:
| Weg | Zeitpunkt |
|---|---|
init({ content }) / initCloud({ content }) | vor dem Mounten |
editor.setContent(content) | bevor der Inhalt die Arbeitsfläche erreicht |
editor.create({ content }) | bevor der Inhalt zum Editor-Status wird |
editor.load(id) | sobald das Ergebnis des templates-Providers zurückkommt |
| Vorschau und Wiederherstellung der Versionshistorie | sobald eine Version die Arbeitsfläche erreicht |
Die Erkennung richtet sich nach Ihrer konfigurierten syntax, nicht nach dem tags-Array — ein nicht deklariertes Token wird also ebenfalls zu einem Tag, beschriftet mit seinem eigenen Rohwert.
Nur Text wird umgewandelt. Ein Token in einem href, src oder einem beliebigen anderen Attribut bleibt Byte für Byte identisch:
html
<!-- vorher -->
<p>Hallo {{first_name}} — <a href="{{unsubscribe_url}}">abmelden</a></p>
<!-- nachher -->
<p>Hallo <span data-merge-tag="{{first_name}}">Vorname</span> —
<a href="{{unsubscribe_url}}">abmelden</a></p>Nur Rich Text wird umgewandelt — TitleBlock.content und ParagraphBlock.content. Jedes andere Merge-Tag-Feld wird als Text gerendert und behält seine reinen Tokens: Schaltflächentext und -URLs, src/alt von Bildern, HtmlBlock.content, Feldwerte benutzerdefinierter Blöcke, settings.preheaderText und Tabellenzellen.
getContent() ist kein Byte-für-Byte-Roundtrip
Die reinen Tokens einer geladenen Vorlage kommen als Tag-Knoten zurück. In Ihren Speicher wird nichts geschrieben, solange Sie nicht speichern, und nichts wird als ungespeicherte Änderung markiert — rechnen Sie aber mit einer einmaligen Abweichung, wenn Sie gespeicherte Vorlagen vergleichen oder Prüfsummen bilden.
Die Ausgabe ist nicht betroffen: toMjml() / toHtml() ersetzen einen Tag-Knoten durch sein Token, sodass eine umgewandelte Vorlage und ihr Original mit reinen Tokens identisch kompilieren.
Einen resolvePreview-Hook schreiben
Ihr resolvePreview-Callback erhält Tag-Knoten, auch für Inhalt, der als reines Token eintraf. Gleichen Sie gegen das Tag-Markup ab, nicht gegen das rohe Token — ein naives replaceAll('{{first_name}}', 'Grace') trifft auch das Token innerhalb von data-merge-tag="{{first_name}}" und erzeugt stillschweigend ein Tag, das sein Label rendert.
Merge-Tags in anderen Eingaben
Merge-Tags sind nicht auf Titel- und Absatzblöcke beschränkt. Der Editor erkennt und hebt Merge-Tags auch in anderen Blockeingaben hervor — Schaltflächentext, Schaltflächen-URL, Bild-URL, Bild-Alternativtext und Link-href-Werte. Das gleiche Label-Ersetzungs- und Tooltip-Verhalten gilt in diesen Feldern.

Link-URLs
Der Dialog Link einfügen in einem Titel- oder Absatzblock nimmt Merge-Tags in seinem URL-Feld entgegen — über dieselbe Einfüge-Schaltfläche, denselben Picker und dieselbe Autovervollständigung wie jedes andere URL-Feld. Ein Link ist häufig empfänger- oder ereignisspezifisch, seine URL also oft ein Tag statt eines Literals.
Eine ohne Schema eingegebene URL wird mit https:// vervollständigt — außer sie beginnt mit einem Merge-Tag, dann wird sie genau so gespeichert, wie Sie sie geschrieben haben:
text
Eingabe gespeicherter href
────────────────────────────── ──────────────────────────────
{{event_url}} → {{event_url}}
{{base_url}}/events/42 → {{base_url}}/events/42
https://acme.com/{{event_id}} → https://acme.com/{{event_id}}
acme.com/promo → https://acme.com/promoDas Tag liefert sein eigenes Schema; ein vorangestelltes Schema ergäbe https://https://…. Die Schema-Positivliste greift weiterhin zuerst, ein Tag kann also kein abgelehntes Schema (javascript:, data:) daran vorbeischmuggeln.
Ein Tag in einem href bleibt beim Export unverändert — siehe Tokens in geladenen Inhalten — das sendende System löst es also auf, genau wie bei einer Schaltflächen-URL.
Merge-Tags außerhalb des Editors verwenden
Der Editor verwaltet Merge-Tags auf allen Oberflächen, die zu ihm gehören — Rich-Text-Blöcke, den Toolbar-Picker und die oben genannten weiteren Blockeingaben. Für Eingaben außerhalb des Editors, etwa ein Betreffzeilenfeld in Ihrer eigenen Anwendung, bauen Sie ein kleines eigenes Feld mit den Merge-Tag-Primitiven, die @templatical/types exportiert. Es sind dieselben Funktionen, die der Editor intern verwendet, sodass Ihr Feld konsistent mit der syntax bleibt, die Sie für den Editor konfiguriert haben.
Das Paket (MIT) exportiert das vollständige Toolkit:
SYNTAX_PRESETS— die integrierten Syntaxdefinitionen (liquid,handlebars,mailchimp,ampscript)getSyntaxTriggerChar/getSyntaxClosingChar— die öffnenden/schließenden Trennzeichen eines Presets, für die Autovervollständigungs-ErkennungisMergeTagValue,getMergeTagLabel,containsMergeTag— Abgleich und Label-AuflösungisLogicMergeTagValue,getLogicMergeTagKeyword— dasselbe für Logik-Tags- die Typen
MergeTagundSyntaxPreset
Einen gespeicherten Wert als Label-Chips darstellen
Teilen Sie eine Rohzeichenkette in Klartext und aufgelöste Tag-Labels auf — im Wesentlichen die Segmentierung des Editors selbst:
ts
import { SYNTAX_PRESETS, getMergeTagLabel, type MergeTag } from '@templatical/types';
const syntax = SYNTAX_PRESETS.liquid;
const tags: MergeTag[] = [{ label: 'First name', value: '{{first_name}}' }];
function segments(value: string) {
const re = new RegExp(syntax.value.source, 'g');
const out: { text: string; isTag: boolean; label?: string }[] = [];
let last = 0;
let m: RegExpExecArray | null;
while ((m = re.exec(value))) {
if (m.index > last) out.push({ text: value.slice(last, m.index), isTag: false });
out.push({ text: m[0], isTag: true, label: getMergeTagLabel(m[0], tags) });
last = m.index + m[0].length;
}
if (last < value.length) out.push({ text: value.slice(last), isTag: false });
return out;
}
// segments('Hi {{first_name}}!') →
// [ { text: 'Hi ', isTag: false },
// { text: '{{first_name}}', isTag: true, label: 'First name' },
// { text: '!', isTag: false } ]Autovervollständigung in einer einfachen Eingabe
Die Trennzeichen-Helfer halten Ihr eigenes Dropdown über alle Presets hinweg syntaxgenau:
ts
import { SYNTAX_PRESETS, getSyntaxTriggerChar, getSyntaxClosingChar } from '@templatical/types';
const syntax = SYNTAX_PRESETS.liquid;
const open = getSyntaxTriggerChar(syntax); // '{{'
const close = getSyntaxClosingChar(syntax); // '}}'
// Prüfen Sie bei jedem Tastendruck den Text vor dem Cursor: Enthält er ein
// nicht geschlossenes `open`-Trennzeichen, nehmen Sie das Fragment danach als
// Suchbegriff und filtern Sie Ihre Tags in ein eigenes Dropdown.Ein eigenes Feld bedeutet, dass es in Ihrem Framework gerendert wird, im Stil Ihres Designsystems und gegen Ihr eigenes Tag-Modell — was für etwas wie eine Betreffzeile in der Regel genau das ist, was Sie möchten.