Ein praktischer Leitfaden zum Schreiben von CEL-Ausdrücken im CMS.
Ein praktischer Leitfaden zum Schreiben von CEL-Ausdrücken im CMS.
CEL (Common Expression Language) ist eine leichtgewichtige Skriptsprache, die in unser CMS integriert ist. Damit lassen sich dynamische Ausdrücke schreiben, die Daten aus Dokumenten ziehen, URL-Parameter lesen und Werte spontan berechnen können.
So läuft ein CEL-Skript ab:
Ihr Skript Die Engine Ergebnis
| | |
v v v
documents.get("article", "intro") --> Ruft aus der Datenbank ab --> { headline: "Willkommen", body: "..." }
.headline --> Extrahiert das Feld --> "Willkommen"
Betrachten Sie CEL als eine schreibgeschützte Abfragesprache. Sie kann nichts in der Datenbank verändern – sie liest nur Daten aus und gibt ein berechnetes Ergebnis zurück. Damit ist sie überall im CMS sicher einsetzbar.
Jeder CEL-Ausdruck hat Zugriff auf drei Dinge:
| Objekt | Was es ist | Beispiel |
|---|---|---|
documents | Ruft jedes Dokument aus dem CMS ab | documents.get("country", "us") |
meta | Informationen über die aktuelle Anfrage (Locale, URL-Parameter) | meta.locale, meta.params.slug |
schema | Felddefinitionen des aktuellen Dokuments | schema.fields |
docWenn Sie CEL-Ausdrücke im Dokumenteneditor schreiben, können Sie über das Objekt doc auf die Feldwerte des aktuellen Dokuments zugreifen. Das ermöglicht berechnete Felder und Feldübergreifende Verweise.
// Zugriff auf das Preisfeld des aktuellen Dokuments
doc.price
// Gesamtbetrag aus Feldern des aktuellen Dokuments berechnen
doc.price * doc.quantity
// Bedingung basierend auf dem Status des aktuellen Dokuments
doc.status == "published" ? doc.title : "Entwurf: " + doc.title
Das Objekt doc enthält alle Feldwerte des bearbeiteten Dokuments. Das ist hilfreich für:
doc.price * doc.quantity)Die stärkste Funktion von CEL ist das Abrufen von Dokumenten aus dem gesamten CMS.
Syntax: documents.get(schemaName, identifier)
Angenommen, Sie haben ein article-Dokument mit dem Bezeichner "welcome-post" gespeichert:
// Im CMS gespeichert als: article / welcome-post
{
"headline": "Willkommen auf unserer Plattform",
"author": "Sarah Chen",
"body": "Wir freuen uns, bekannt zu geben...",
"tags": ["ankündigung", "nachrichten"]
}
So holen Sie das gesamte Dokument:
documents.get("article", "welcome-post")
Ergebnis:
{
"headline": "Willkommen auf unserer Plattform",
"author": "Sarah Chen",
"body": "Wir freuen uns, bekannt zu geben...",
"tags": ["ankündigung", "nachrichten"]
}
Nur die Überschrift holen:
documents.get("article", "welcome-post").headline
Ergebnis: "Willkommen auf unserer Plattform"
Die Autorin abrufen:
documents.get("article", "welcome-post").author
Ergebnis: "Sarah Chen"
Wenn Ihre Seite dynamische Routen hat (z. B. /articles/[slug]), können Sie meta.params nutzen, um den URL-Parameter abzurufen und das richtige Dokument zu holen.
Besucht jemand /articles/welcome-post:
documents.get("article", meta.params.slug).headline
Ergebnis: "Willkommen auf unserer Plattform"
So erstellen Sie dynamische Seiten – dasselbe CEL-Skript funktioniert für jeden Artikel und verwendet einfach den Slug aus der URL.
Syntax: documents.find(schemaName) oder documents.find(schemaName, filter)
// Alle Länder abrufen
documents.find("country")
Ergebnis:
[
{ "code": "us", "name": "Vereinigte Staaten", "flag": "US" },
{ "code": "sa", "name": "Saudi-Arabien", "flag": "SA" },
{ "code": "gb", "name": "Vereinigtes Königreich", "flag": "GB" }
// Länder mit Filter abrufen
documents.find("country", { "where": { "code": "us" } })
Ergebnis:
[
{ "code": "us", "name": "Vereinigte Staaten", "flag": "US" }
]
CEL unterstützt das Abrufen übersetzter Dokumentinhalte auf zwei Arten: automatische, locale-basierte Übersetzung und explizite Übersetzungssuche.
Wenn meta.locale gesetzt ist (z. B. über Routenparameter oder Benutzerpräferenzen), fügt documents.get() automatisch übersetzte Inhalte zusammen:
// Wenn meta.locale "fr" ist, wird die französische Übersetzung mit dem Basisdokument zusammengeführt
documents.get("greeting", "welcome").headline
So funktioniert es:
meta.locale nicht "en" oder "en-US" ist, wird die Übersetzung in der Tabelle translations gesucht{ ...baseContent, ...translatedContent }Damit überschreiben übersetzte Felder die Basisfelder, während nicht übersetzte Felder auf das Basisdokument zurückfallen.
Für Fälle, in denen Sie eine bestimmte Übersetzung unabhängig von der aktuellen Locale abrufen müssen:
Syntax: documents.translated(schemaName, identifier, locale)
// Immer die spanische Übersetzung abrufen
documents.translated("greeting", "welcome", "es").headline
// Übersetzung basierend auf URL-Parametern abrufen
documents.translated("product", meta.params.id, meta.params.lang).description
// Übersetzungen vergleichen
documents.translated("article", "intro", "en").title + " / " + documents.translated("article", "intro", "fr").title
Ihre Begrüßungsdokumente mit Übersetzungen:
// Basisdokument: greeting / welcome
{ "headline": "Willkommen", "subheadline": "Willkommen auf unserer Plattform" }
// Übersetzung (Sprache: "fr")
{ "headline": "Bienvenue", "subheadline": "Bienvenue sur notre plateforme" }
// Übersetzung (Sprache: "es")
{ "headline": "Bienvenido", "subheadline": "Bienvenido a nuestra plataforma" }
CEL-Skripte:
// Mit meta.locale = "fr"
documents.get("greeting", "welcome").headline
// Ergebnis: "Bienvenue"
// Explizite spanische Übersetzung
documents.translated("greeting", "welcome", "es").headline
// Ergebnis: "Bienvenido"
// Fallback-Muster für fehlende Übersetzungen
documents.translated("greeting", "welcome", meta.params.lang) != null
? documents.translated("greeting", "welcome", meta.params.lang).headline
: documents.get("greeting", "welcome").headline
Sie haben einen hero-block, der eine Überschrift aus einem article-Dokument anzeigen soll.
Ihr Artikeldokument (Bezeichner: "homepage-hero"):
{
"headline": "Schneller entwickeln, smarter ausliefern",
"subheadline": "Das moderne CMS für Entwicklerinnen und Entwickler"
}
CEL-Skript im Titelfeld des Hero-Blocks:
documents.get("article", "homepage-hero").headline
Ergebnis: Der Hero zeigt "Schneller entwickeln, smarter ausliefern"
Sie erstellen eine Seite unter /countries/[code] und möchten den vollständigen Ländernamen anzeigen.
Ihre Länderdokumente:
// country / us
{ "code": "us", "name": "Vereinigte Staaten", "flag": "US", "languages": ["en", "es"] }
// country / sa
{ "code": "sa", "name": "Saudi-Arabien", "flag": "SA", "languages": ["ar", "en"
CEL-Skript:
documents.get("country", meta.params.code).name
Wenn jemand /countries/us besucht:
meta.params.code = "us""Vereinigte Staaten"Wenn jemand /countries/sa besucht:
meta.params.code = "sa""Saudi-Arabien"Zeigen Sie unterschiedliche Überschriften abhängig von der Locale der Nutzerin oder des Nutzers.
meta.locale == "ar-SA" ? "Willkommen, alle zusammen" : "Willkommen"
Wenn die Locale "ar-SA" ist: Ergebnis "Willkommen, alle zusammen"
Wenn die Locale etwas anderes ist: Ergebnis "Willkommen"
Ihr article enthält ein Feld countryCode, und Sie möchten den vollen Ländernamen abrufen.
Artikeldokument:
{ "headline": "Neuigkeiten aus den USA", "countryCode": "us" }
CEL-Skript:
documents.get("country", documents.get("article", "us-news").countryCode).name
Was passiert:
documents.get("article", "us-news") gibt { "headline": "Neuigkeiten aus den USA", "countryCode": "us" } zurück.countryCode extrahiert "us"documents.get("country", "us") gibt { "code": "us", "name": "Vereinigte Staaten", ... } zurück.name extrahiert "Vereinigte Staaten"Ergebnis: "Vereinigte Staaten"
Wenn ein Dokument möglicherweise nicht existiert, können Sie einen Fallback angeben:
documents.get("article", meta.params.slug) != null
? documents.get("article", meta.params.slug).headline
: "Artikel nicht gefunden"
Oder prüfen, ob ein bestimmtes Feld existiert:
documents.get("article", "intro").author != null
? documents.get("article", "intro").author
: "Unbekannte Autorin"
Ihr Artikel hat Tags und Sie möchten prüfen, ob ein bestimmter Tag vorhanden ist:
"featured" in documents.get("article", "welcome-post").tags
Ergebnis: true, wenn der Artikel den Tag "featured" hat
Den ersten Tag holen:
documents.get("article", "welcome-post").tags[0]
Ergebnis: "ankündigung" (der erste Tag)
Tags zählen:
size(documents.get("article", "welcome-post").tags)
Ergebnis: 2 (Anzahl der Tags)
Parametrische Routen sind der Schlüssel zum Aufbau dynamischer, lokalisierter Seiten. Wenn Sie ein Routenmuster wie /{lang}/landingPage definieren, extrahiert das CMS Parameter aus der URL und stellt sie über meta.params bereit.
Definition des Routenmusters:
Routen verwenden die Syntax :paramName oder {paramName}, um dynamische Segmente zu definieren:
| Muster | Beispiel-URL | Extrahierte Parameter |
|---|---|---|
/:lang/landingPage | /ko/landingPage | { lang: "ko" } |
/{country}/{lang}/products | /us/en/products | { country: "us", lang: "en" } |
/articles/:slug | /articles/welcome-post | { slug: "welcome-post" } |
Parameter-Bindings: Jeder Routenparameter kann zur Validierung an ein Dokumentenschema gebunden werden:
{
"pattern": "/{lang}/landingPage",
"param_bindings": {
"lang": "language"
}
}
Diese Bindung teilt dem CMS mit:
lang aus der URL extrahierenlanguage-Schema validieren (sucht nach einem Dokument, bei dem content.code übereinstimmt)Routenkonfiguration:
/{lang}/landingPage/{lang}/landingPage{ "lang": "language" }Ihre Begrüßungsdokumente:
// greeting / ko
{ "code": "ko", "headline": "Willkommen", "subheadline": "Willkommen auf unserer Plattform", "ctaText": "Loslegen", "ctaUrl": "/ko/get-started" }
// greeting / en
{ "code": "en", "headline": "Willkommen", "subheadline"
CEL-Skript zum Abrufen lokalisierter Inhalte:
documents.get("greeting", meta.params.lang).headline
So wird aufgelöst:
| URL | meta.params.lang | Ergebnis |
|---|---|---|
/ko/landingPage | "ko" | "Willkommen" |
/en/landingPage | "en" | "Willkommen" |
/ja/landingPage | "ja" | "Willkommen" |
Für Routen wie /{country}/{lang}/products:
Routenkonfiguration:
{
"pattern": "/{country}/{lang}/products",
"param_bindings": {
"country": "country",
"lang": "language"
}
}
CEL-Skripte:
// Ländernamen abrufen
documents.get("country", meta.params.country).name
// Lokalisierte Produktliste basierend auf dem Land abrufen
documents.find("product", { "where": { "country": meta.params.country } })
// Kombiniert: Länderspezifische Begrüßung in der Sprache der Nutzerin oder des Nutzers
documents.get("greeting", meta.params.lang).headline + " aus " + documents.get("country", meta.params.country).name
Validierungskaskade:
Das CMS validiert Parameter hierarchisch. Für Routen /{country}/{lang} gilt:
country-Parameter gegen das country-Schema validierenlang-Parameter gegen das language-Schema validierenlang im Array country.languages[] enthalten ist (hierarchische Validierung)meta.segments liefert den rohen URL-Pfad als Array. Das ist nützlich, wenn Sie positionalen Zugriff ohne benannte Parameter benötigen.
So funktioniert es:
| URL-Pfad | meta.segments |
|---|---|
/articles/tech/ai-news | ["articles", "tech", "ai-news"] |
/ko/landingPage | ["ko", "landingPage"] |
/us/en/products/featured | ["us", "en", "products", "featured"] |
/ | [] |
| Anwendungsfall | Beste Wahl |
|---|---|
| Benannte Parameter aus dem Routenmuster | meta.params.lang |
| Positionsbasierter Zugriff | meta.segments[0] |
| Pfadtiefe ermitteln | size(meta.segments) |
| Prüfen, ob Pfad Segment enthält | "admin" in meta.segments |
// Erstes Segment holen (oft Sprachcode)
meta.segments[0]
// Pfadtiefe prüfen
size(meta.segments) > 2 ? "tief" : "flach"
// Prüfen, ob wir im Admin-Bereich sind
"admin" in meta.segments ? "Admin-Modus" : "Öffentlicher Modus"
// Fallback: Segment verwenden, wenn Parameter nicht gebunden ist
has(meta.params.lang) ? meta.params.lang : meta.segments[0]
Das Objekt meta enthält den gesamten Kontext zur aktuellen Anfrage:
| Eigenschaft | Typ | Beschreibung | |
|---|---|---|---|
meta.locale | string | Aktueller Locale-Code (z. B. "en-US", "ko-KR", "ar-SA") | |
meta.params | Record<string, string> | Aus dem URL-Muster extrahierte Routenparameter | |
meta.segments | string[] | In Segmente aufgeteilter URL-Pfad | |
meta.docId | `string \ | null` | UUID des aktuellen Dokuments (null bei neuen Dokumenten) |
meta.title | string | Titel des aktuellen Dokuments |
Der Locale-Code folgt dem BCP-47-Format (Sprache-Region):
// Locale auf RTL-Sprachen prüfen
meta.locale == "ar-SA" || meta.locale == "he-IL" ? "rtl" : "ltr"
// Nur den Sprachteil holen
meta.locale.split("-")[0] // Nicht unterstützt – verwenden Sie stattdessen meta.params.lang
Routenparameter sind immer Strings. Das CMS validiert sie vor der Auswertung gegen die gebundenen Schemata:
// Benannten Parameter abrufen
meta.params.lang // "ko"
meta.params.country // "us"
meta.params.slug // "welcome-post"
// Prüfen, ob Parameter existiert
has(meta.params.category) // true/false
// In Dokumentabruf verwenden
documents.get("greeting", meta.params.lang)
documents.ref("airports").get(meta.params.code)
Rohe URL-Segmente als Array:
// Zugriff per Index (0-basiert)
meta.segments[0] // Erstes Segment
meta.segments[1] // Zweites Segment
// Länge prüfen
size(meta.segments) // Anzahl der Segmente
// Mitgliedschaft prüfen
"products" in meta.segments // Enthält der Pfad "products"?
Die UUID des aktuellen Dokuments, nützlich für selbstreferenzierende Skripte:
// Nur verfügbar beim Bearbeiten bestehender Dokumente
meta.docId != null ? "Bearbeitung" : "Neues Dokument"
// In Bedingungslogik verwenden
meta.docId != null ? documents.get("article", meta.docId).status : "draft"
Der Titel des aktuellen Dokuments:
// Zur Anzeige nutzen
"Bearbeite: " + meta.title
// Bedingung basierend auf dem Titel
meta.title.contains("Draft") ? "In Arbeit" : "Veröffentlicht"
Für eine übersichtlichere Syntax, wenn das Schema bekannt ist, der Bezeichner aber dynamisch:
// Traditioneller Ansatz
documents.get("airports", meta.params.code).name
// Mit ref() – Schema getrennt vom dynamischen Bezeichner
documents.ref("airports").get(meta.params.code).name
Beides ist äquivalent, aber ref() macht den dynamischen Teil klarer.
documents.get("schema", "identifier") // Ein Dokument abrufen
documents.get("schema", "id").fieldName // Spezifisches Feld abrufen
documents.find("schema") // Alle Dokumente abrufen
documents.find("schema", { "where": {...}}) // Gefilterte Abfrage
documents.ref("schema").get(identifier) // Verketteter Abruf
documents.translated("schema", "id", "fr") // Mit expliziter Locale abrufen
meta.locale // "en-US", "ar-SA" usw.
meta.params.xyz // URL-Parameter mit Namen "xyz"
meta.segments // URL-Pfad als Array: ["articles", "intro"]
meta.segments[0] // Erstes Pfadsegment
meta.docId // Aktuelle Dokument-ID (oder null)
meta.title // Titel des aktuellen Dokuments
doc.fieldName // Feldwert des aktuellen Dokuments (im Editor-Kontext)
// Vergleich
== != < <= > >=
// Logik
&& || !
// Ternär (if-else)
Bedingung ? WertWennWahr : WertWennFalsch
// Mitgliedschaft
"Wert" in listeOderMap
size(list) // Anzahl der Elemente
size(string) // Stringlänge
"text".startsWith("te") // true
"text".endsWith("xt") // true
"text".contains("ex") // true
has(object.property) // Prüfen, ob Eigenschaft existiert
hasProperty(obj, "key") // Prüfen, ob Objekt Schlüssel hat (alternative Syntax)
Wenn etwas schiefgeht, sehen Sie eine dieser Meldungen:
| Fehler | Bedeutung |
|---|---|
SYNTAX_ERROR | Tippfehler im Skript (fehlendes Anführungszeichen, falscher Operator) |
TYPE_ERROR | Sie mischen inkompatible Typen |
RUNTIME_ERROR | Das Skript lief, stieß aber auf ein Problem (undefinierte Variable) |
FETCH_LIMIT_EXCEEDED | Es werden zu viele Dokumente abgerufen (maximal 50) |
TIMEOUT | Skript dauerte zu lange (maximal 5 Sekunden) |
AST_DEPTH_EXCEEDED | Ausdruck zu tief verschachtelt (maximale Tiefe: 50) |
SCRIPT_TOO_LONG | Skript überschreitet das Limit von 5000 Zeichen |
Die CEL-Engine ist auf Erweiterbarkeit ausgelegt. Geplante zukünftige Funktionen umfassen:
// Zukunft: Externe Dienste über MCP aufrufen
mcp.translate(meta.params.text, "en", meta.params.lang)
mcp.analyze(documents.get("article", meta.params.id).body)
// Zukunft: KI-gestützte Inhaltserzeugung
ai.summarize(documents.get("article", meta.params.id).body, 100)
ai.translate(meta.params.text, meta.params.targetLang)
ai.classify(meta.params.input, ["positive", "negative", "neutral"])
Diese Funktionen werden über das registrierte Funktionssystem hinzugefügt und bleiben rückwärtskompatibel mit bestehenden Skripten.
documents. oder meta., und der Editor zeigt verfügbare Optionen andocuments.get("schema", "id") und fügen Sie dann .fieldName hinzu!= null ? ... : ... eindocuments.get() oder documents.find() zählt gegen das 50-Abruf-Limithas(meta.params.category), bevor Sie darauf zugreifenDieser Abschnitt behandelt fortgeschrittene Muster, um Dokumente miteinander zu verknüpfen und relationale Inhaltsstrukturen aufzubauen.
Der simpelste Fall: Ein Dokument verweist über einen Bezeichner auf ein anderes.
// Artikel speichert Autor-ID, Name der Autorin abrufen
documents.get("author", documents.get("article", "intro").authorId).name
Für eine klarere Syntax, wenn der Bezeichner dynamisch ist:
// Traditioneller Ansatz
documents.get("country", documents.get("airport", meta.params.code).countryCode).name
// Mit ref() – klarer, wenn Schema bekannt, Bezeichner dynamisch
documents.ref("country").get(documents.get("airport", meta.params.code).countryCode).name
Bauen Sie tiefe Beziehungen auf, indem Sie mehrere Abrufe verketten:
// Flughafen → Land → Region → Kontinent
documents.get("continent",
documents.get("region",
documents.get("country",
documents.get("airport", meta.params.code).countryCode
).regionCode
).continentCode
).name
Dokumentenverweise mit Übersetzungen kombinieren:
// Lokalisierter Ländername für einen Flughafen
documents.translated("country",
documents.get("airport", meta.params.code).countryCode,
meta.params.lang
).name
Ein Dokument speichert eine ID, die auf ein anderes Dokument verweist.
// article / tech-news
{ "title": "Technik-Update", "authorId": "author-123", "categoryId": "cat-tech" }
// Namen der Autorin auflösen
documents.get("author", documents.get("article", meta.params.slug).authorId).name
// Kategorie mit Fallback auflösen
documents.get("article", meta.params.slug).categoryId != null
? documents.get("category", documents.get("article", meta.params.slug).categoryId).name
: "Keine Kategorie"
Dokumente verweisen über semantische Codes anstelle von UUIDs aufeinander.
// airport / JFK
{ "code": "JFK", "name": "John F. Kennedy International", "countryCode": "us" }
// country / us
{ "code": "us", "name": "Vereinigte Staaten", "currencyCode": "usd" }
// currency / usd
{ "code": "usd", "symbol"
// Flughafen → Land → Währung
documents.get("currency",
documents.get("country",
documents.get("airport", meta.params.code).countryCode
).currencyCode
).symbol
// Für JFK: Gibt "$" zurück
Verwenden Sie doc für berechnete Felder, die andere Dokumente anhand der Werte des aktuellen Dokuments referenzieren.
// In einem Produktdokument die zugehörige Kategoriebeschreibung abrufen
documents.get("category", doc.categoryId).description
// Versandkosten basierend auf dem Herkunftsland des Produkts berechnen
documents.get("shipping-rates", doc.originCountry).baseRate * doc.weight
Wenn Dokumente sich gegenseitig referenzieren, achten Sie auf Abruflimits.
// Autorin eines Artikels abrufen und dann deren andere Artikel (Abrufzahl im Blick behalten!)
documents.find("article", { "where": { "authorId": documents.get("article", meta.params.slug).authorId } })
Wenn ein Feld auf unterschiedliche Schemata verweisen kann:
// content-block / hero-1
{ "type": "hero", "sourceType": "article", "sourceId": "welcome-post" }
// content-block / hero-2
{ "type": "hero", "sourceType": "product", "sourceId": "featured-item" }
// Dynamisches Schema basierend auf sourceType
documents.get("content-block", "hero-1").sourceType == "article"
? documents.get("article", documents.get("content-block", "hero-1").sourceId).headline
: documents.get("product", documents.get("content-block", "hero-1").sourceId).name
Jeder Aufruf von documents.get(), documents.find() und documents.ref().get() wird für die Cache-Invalidierung nachverfolgt. Sobald sich ein referenziertes Dokument ändert, weiß das CMS, welche CEL-Ausdrücke neu ausgewertet werden müssen.
Verfolgte Abhängigkeiten umfassen:
schema:identifier – Abhängigkeit von einem konkreten Dokumentschema:identifier – Wie get, aber über die verkettete Syntaxschema:* – Schemaweite Abhängigkeit (jedes Dokument im Schema)// Schlecht: Holt dasselbe Dokument zweimal
documents.get("author", documents.get("article", "intro").authorId).name + " - " +
documents.get("author", documents.get("article", "intro").authorId).bio
// Besser: Einmal prüfen und verwenden
documents.get("article", "intro").authorId != null
? documents.get("author", documents.get("article", "intro").authorId).name
: "Unbekannte Autorin"
Dieser Leitfaden erstellt eine mehrsprachige Landingpage, erreichbar unter /{lang}/landingPage.
Erstellen Sie im CMS-Admin ein benutzerdefiniertes Schema namens greeting:
{
"name": "greeting",
"fields": [
{ "name": "code", "type": "string", "required": true },
{ "name": "headline", "type": "string", "required": true },
{ "name": "subheadline"
Erstellen Sie Dokumente für jede Sprache:
Dokument: greeting / ko
{
"code": "ko",
"headline": "Willkommen",
"subheadline": "Willkommen auf unserer Plattform",
"ctaText": "Loslegen",
"ctaUrl": "/ko/get-started"
}
Dokument: greeting / en
{
"code": "en",
"headline": "Willkommen",
"subheadline": "Willkommen auf unserer Plattform",
"ctaText": "Jetzt starten",
"ctaUrl": "/en/get-started"
}
Dokument: greeting / ja
{
"code": "ja",
"headline": "Willkommen",
"subheadline": "Willkommen auf unserer Plattform",
"ctaText": "Start",
"ctaUrl": "/ja/get-started"
}
Legen Sie eine Route mit folgender Konfiguration an:
/{lang}/landingPage/{lang}/landingPage {
"lang": "language"
}
Fügen Sie der Route einen Hero-Block hinzu und verwenden Sie diese CEL-Skripte für die einzelnen Felder:
Überschriftenfeld:
documents.get("greeting", meta.params.lang).headline
Unterüberschriftenfeld:
documents.get("greeting", meta.params.lang).subheadline
CTA-Text-Feld:
documents.get("greeting", meta.params.lang).ctaText
CTA-URL-Feld:
documents.get("greeting", meta.params.lang).ctaUrl
Erstellen Sie eine Catch-all-Route in Ihrer Next.js-App:
// app/[...slug]/page.tsx
import { getCmsClient } from '@repo/renderer';
interface PageProps {
params: { slug: string[] };
}
export default async function Page({ params }: PageProps) {
Besuchen Sie diese URLs, um lokalisierte Inhalte anzuzeigen:
| URL | Erwartete Überschrift |
|---|---|
/ko/landingPage | Welcome |
/en/landingPage | Welcome |
/ja/landingPage | Welcome |
Wenn jemand /ko/landingPage besucht:
/{lang}/landingPagemeta.params.lang = "ko"language-Schemadocuments.get("greeting", meta.params.lang) liefern koreanische Inhalteinterface CelMeta {
/** Aktueller Locale-Code (z. B. 'en-US') */
locale: string;
/** Aus der URL extrahierte Routenparameter */
params: Record<string, string>;
/** URL-Pfadsegmente */
segments: string[];
/** ID des aktuellen Dokuments (bei Bearbeitung) */
Die Funktion extractParams verarbeitet URL-Pfade:
Muster: /{country}/{lang}/products
Pfad: /us/en/products
Algorithmus:
1. Beide normalisieren (abschließende Slashes entfernen)
2. In Segmente teilen: ["us", "en", "products"] und ["{country}", "{lang}", "products"
// Einfache Bindung (nutzt das Feld "code" zur Suche)
{ "lang": "language" }
// Detaillierte Bindung (benutzerdefiniertes Slug-Feld)
{
"lang": {
"schemaName": "language",
"slugField": "code"
},
"slug": {
"schemaName": "article",
"slugField": "slug"
}
Beim Abruf über documents.get(schema, identifier) gilt:
idcontent.codecontent.slugtitleSo können Dokumente flexibel über jeden eindeutigen Identifikator referenziert werden.