Een praktische gids voor het schrijven van CEL-expressies in het CMS.
Een praktische gids voor het schrijven van CEL-expressies in het CMS.
CEL (Common Expression Language) is een lichtgewicht scripttaal die in ons CMS is ingebouwd. Hiermee kun je dynamische expressies schrijven die gegevens uit documenten ophalen, URL-parameters lezen en ter plekke waarden berekenen.
Dit gebeurt er wanneer een CEL-script wordt uitgevoerd:
Jouw script De engine Resultaat
| | |
v v v
documents.get("article", "intro") --> Haalt op uit de database --> { headline: "Welkom", body: "..." }
.headline --> Extraheert het veld --> "Welkom"
Zie CEL als een alleen-lezen querytaal. Het kan niets in de database aanpassen: het leest enkel gegevens en geeft een berekend resultaat terug. Hierdoor is het veilig om overal in het CMS te gebruiken.
Elke CEL-expressie heeft toegang tot drie zaken:
| Object | Wat het is | Voorbeeld |
|---|---|---|
documents | Haal elk document uit het CMS | documents.get("country", "us") |
meta | Informatie over het huidige verzoek (locale, URL-params) | meta.locale, meta.params.slug |
schema | De velddefinities van het huidige document | schema.fields |
docWanneer je CEL-expressies schrijft binnen een documenteditor, kun je de veldwaarden van het huidige document benaderen via het doc-object. Hierdoor worden berekende velden en kruisverwijzingen tussen velden mogelijk.
// Toegang tot het prijsveld van het huidige document
doc.price
// Totaal berekenen op basis van velden in het huidige document
doc.price * doc.quantity
// Voorwaarde op basis van de status van het huidige document
doc.status == "published" ? doc.title : "Concept: " + doc.title
Het doc-object bevat alle veldwaarden van het document dat je bewerkt. Dit is nuttig voor:
doc.price * doc.quantity)De krachtigste functie van CEL is het ophalen van documenten overal uit je CMS.
Syntaxis: documents.get(schemaName, identifier)
Stel, je hebt een article-document met de identifier "welcome-post" opgeslagen:
// Opgeslagen in het CMS als: article / welcome-post
{
"headline": "Welkom op ons platform",
"author": "Sarah Chen",
"body": "We zijn verheugd aan te kondigen...",
"tags": ["announcement", "news"]
}
Om het hele document op te halen:
documents.get("article", "welcome-post")
Geeft terug:
{
"headline": "Welkom op ons platform",
"author": "Sarah Chen",
"body": "We zijn verheugd aan te kondigen...",
"tags": ["announcement", "news"]
}
Om alleen de headline op te halen:
documents.get("article", "welcome-post").headline
Geeft terug: "Welkom op ons platform"
Om de auteur op te halen:
documents.get("article", "welcome-post").author
Geeft terug: "Sarah Chen"
Wanneer je pagina dynamische routes heeft (zoals /articles/[slug]), kun je meta.params gebruiken om de URL-parameter op te halen en het juiste document te laden.
Als iemand /articles/welcome-post bezoekt:
documents.get("article", meta.params.slug).headline
Geeft terug: "Welkom op ons platform"
Zo bouw je dynamische pagina's: hetzelfde CEL-script werkt voor elk artikel, en gebruikt simpelweg de slug uit de URL.
Syntaxis: documents.find(schemaName) of documents.find(schemaName, filter)
// Haal alle landen op
documents.find("country")
Geeft terug:
[
{ "code": "us", "name": "Verenigde Staten", "flag": "US" },
{ "code": "sa", "name": "Saoedi-Arabië", "flag": "SA" },
{ "code": "gb", "name": "Verenigd Koninkrijk", "flag": "GB" }
]
// Haal landen op met een filter
documents.find("country", { "where": { "code": "us" } })
Geeft terug:
[
{ "code": "us", "name": "Verenigde Staten", "flag": "US" }
]
CEL ondersteunt het ophalen van vertaalde documentinhoud op twee manieren: automatische vertaling op basis van locale en expliciete vertaalopvraging.
Wanneer meta.locale is ingesteld (bijv. via routeparameters of gebruikersvoorkeuren), voegt documents.get() automatisch vertaalde inhoud samen:
// Als meta.locale "fr" is, wordt de Franse vertaling samengevoegd met het basisdocument
documents.get("greeting", "welcome").headline
Hoe het werkt:
meta.locale niet "en" of "en-US" is, wordt de vertaling opgezocht in de tabel translations{ ...baseContent, ...translatedContent }Dit betekent dat vertaalde velden de basisvelden overschrijven, terwijl onvertaalde velden terugvallen op het basisdocument.
Voor situaties waarin je een specifieke vertaling nodig hebt, ongeacht de huidige locale:
Syntaxis: documents.translated(schemaName, identifier, locale)
// Altijd de Spaanse vertaling ophalen
documents.translated("greeting", "welcome", "es").headline
// Vertaling ophalen op basis van URL-parameter
documents.translated("product", meta.params.id, meta.params.lang).description
// Vertalingen vergelijken
documents.translated("article", "intro", "en").title + " / " + documents.translated("article", "intro", "fr").title
Je greeting-documenten met vertalingen:
// Basisdocument: greeting / welcome
{ "headline": "Welkom", "subheadline": "Welkom op ons platform" }
// Vertaling (taal: "fr")
{ "headline": "Bienvenue", "subheadline": "Bienvenue sur notre plateforme" }
// Vertaling (taal: "es")
{ "headline": "Bienvenido", "subheadline": "Bienvenido a nuestra plataforma" }
CEL-scripts:
// Met meta.locale = "fr"
documents.get("greeting", "welcome").headline
// Geeft terug: "Bienvenue"
// Expliciete Spaanse vertaling
documents.translated("greeting", "welcome", "es").headline
// Geeft terug: "Bienvenido"
// Fallback-patroon voor ontbrekende vertalingen
documents.translated("greeting", "welcome", meta.params.lang) != null
? documents.translated("greeting", "welcome", meta.params.lang).headline
: documents.get("greeting", "welcome").headline
Je hebt een hero-block dat een headline moet tonen uit een article-document.
Je artikeldocument (identifier: "homepage-hero"):
{
"headline": "Bouw sneller, lever slimmer",
"subheadline": "Het moderne CMS voor ontwikkelaars"
}
CEL-script in het titelfeld van het hero-blok:
documents.get("article", "homepage-hero").headline
Resultaat: De hero toont "Bouw sneller, lever slimmer"
Je bouwt een pagina op /countries/[code] en wilt de volledige landnaam tonen.
Je landdocumenten:
// country / us
{ "code": "us", "name": "Verenigde Staten", "flag": "US", "languages": ["en", "es"] }
// country / sa
{ "code": "sa", "name": "Saoedi-Arabië", "flag": "SA", "languages": ["ar", "en"] }
CEL-script:
documents.get("country", meta.params.code).name
Wanneer iemand /countries/us bezoekt:
meta.params.code = "us""Verenigde Staten"Wanneer iemand /countries/sa bezoekt:
meta.params.code = "sa""Saoedi-Arabië"Toon verschillende headlines op basis van de locale van de gebruiker.
meta.locale == "ar-SA" ? "Welkom, iedereen" : "Welkom"
Als locale "ar-SA" is: Geeft "Welkom, iedereen"
Als locale iets anders is: Geeft "Welkom"
Je article heeft een veld countryCode, en je wilt de volledige landnaam ophalen.
Artikeldocument:
{ "headline": "Nieuws uit de VS", "countryCode": "us" }
CEL-script:
documents.get("country", documents.get("article", "us-news").countryCode).name
Wat er gebeurt:
documents.get("article", "us-news") geeft { "headline": "Nieuws uit de VS", "countryCode": "us" }.countryCode haalt "us" opdocuments.get("country", "us") geeft { "code": "us", "name": "Verenigde Staten", ... }.name haalt "Verenigde Staten" opResultaat: "Verenigde Staten"
Als een document mogelijk niet bestaat, kun je een fallback bieden:
documents.get("article", meta.params.slug) != null
? documents.get("article", meta.params.slug).headline
: "Artikel niet gevonden"
Of controleer of een specifiek veld bestaat:
documents.get("article", "intro").author != null
? documents.get("article", "intro").author
: "Onbekende auteur"
Je artikel heeft tags en je wilt controleren of een specifieke tag bestaat:
"featured" in documents.get("article", "welcome-post").tags
Geeft: true als het artikel de tag "featured" heeft
De eerste tag ophalen:
documents.get("article", "welcome-post").tags[0]
Geeft: "announcement" (de eerste tag)
De tags tellen:
size(documents.get("article", "welcome-post").tags)
Geeft: 2 (aantal tags)
Parametrische routes zijn de sleutel tot het bouwen van dynamische, gelokaliseerde pagina's. Wanneer je een routepatroon zoals /{lang}/landingPage definieert, haalt het CMS parameters uit de URL en stelt ze beschikbaar via meta.params.
Routepatroonomschrijving:
Routes gebruiken de syntaxis :paramName of {paramName} om dynamische segmenten te definiëren:
| Patroon | Voorbeeld-URL | Extracted params |
|---|---|---|
/:lang/landingPage | /ko/landingPage | { lang: "ko" } |
/{country}/{lang}/products | /us/en/products | { country: "us", lang: "en" } |
/articles/:slug | /articles/welcome-post | { slug: "welcome-post" } |
Parameterkoppelingen: Elk routeparameter kan aan een documentschema worden gekoppeld voor validatie:
{
"pattern": "/{lang}/landingPage",
"param_bindings": {
"lang": "language"
}
}
Deze koppeling vertelt het CMS:
lang uit de URLlanguage (zoekt een document waarbij content.code overeenkomt)Routeconfiguratie:
/{lang}/landingPage/{lang}/landingPage{ "lang": "language" }Je greeting-documenten:
// greeting / ko
{ "code": "ko", "headline": "Welkom", "subheadline": "Welkom op ons platform", "ctaText": "Aan de slag", "ctaUrl": "/ko/get-started" }
// greeting / en
{ "code": "en", "headline": "Welkom", "subheadline": "Welkom op ons platform", "ctaText": "Aan de slag", "ctaUrl": "/en/get-started" }
// greeting / ja
{ "code": "ja", "headline": "Welkom", "subheadline": "Welkom op ons platform", "ctaText": "Start", "ctaUrl": "/ja/get-started" }
CEL-script om gelokaliseerde inhoud op te halen:
documents.get("greeting", meta.params.lang).headline
Hoe dit wordt opgelost:
| URL | meta.params.lang | Resultaat |
|---|---|---|
/ko/landingPage | "ko" | "Welkom" |
/en/landingPage | "en" | "Welkom" |
/ja/landingPage | "ja" | "Welkom" |
Voor routes zoals /{country}/{lang}/products:
Routeconfiguratie:
{
"pattern": "/{country}/{lang}/products",
"param_bindings": {
"country": "country",
"lang": "language"
}
}
CEL-scripts:
// Landnaam ophalen
documents.get("country", meta.params.country).name
// Gelokaliseerde productlijst op basis van land
documents.find("product", { "where": { "country": meta.params.country } })
// Gecombineerd: toon land-specifieke begroeting in de taal van de gebruiker
documents.get("greeting", meta.params.lang).headline + " uit " + documents.get("country", meta.params.country).name
Validatiekaskade:
Het CMS valideert parameters hiërarchisch. Voor routes /{country}/{lang}:
country tegen het schema countrylang tegen het schema languagelang voorkomt in de array country.languages[] (hiërarchische validatie)meta.segments geeft het ruwe URL-pad als een array, handig wanneer je positionele toegang nodig hebt zonder benoemde parameters.
Hoe het werkt:
| URL-pad | meta.segments |
|---|---|
/articles/tech/ai-news | ["articles", "tech", "ai-news"] |
/ko/landingPage | ["ko", "landingPage"] |
/us/en/products/featured | ["us", "en", "products", "featured"] |
/ | [] |
| Use case | Beste aanpak |
|---|---|
| Benoemde parameters uit het routepatroon | meta.params.lang |
| Toegang op basis van positie | meta.segments[0] |
| Pad-diepte ophalen | size(meta.segments) |
| Controleren of het pad een segment bevat | "admin" in meta.segments |
// Eerste segment ophalen (vaak taalcode)
meta.segments[0]
// Pad-diepte controleren
size(meta.segments) > 2 ? "diep" : "oppervlakkig"
// Controleren of we in het beheergedeelte zitten
"admin" in meta.segments ? "adminmodus" : "openbare modus"
// Fallback: gebruik segment als param niet is gekoppeld
has(meta.params.lang) ? meta.params.lang : meta.segments[0]
Het meta-object bevat alle context over het huidige verzoek:
| Eigenschap | Type | Beschrijving | |
|---|---|---|---|
meta.locale | string | Huidige localecode (bijv. "en-US", "ko-KR", "ar-SA") | |
meta.params | Record<string, string> | Routeparameters die uit het URL-patroon zijn gehaald | |
meta.segments | string[] | URL-pad opgesplitst in segmenten | |
meta.docId | string \| null | UUID van het huidige document (null voor nieuwe documenten) | |
meta.title | string | Titel van het huidige document |
De localecode volgt de BCP 47-notatie (taal-regio):
// Locale controleren voor RTL-talen
meta.locale == "ar-SA" || meta.locale == "he-IL" ? "rtl" : "ltr"
// Alleen het taalgedeelte ophalen
meta.locale.split("-")[0] // Niet ondersteund - gebruik in plaats daarvan meta.params.lang
Routeparameters zijn altijd strings. Het CMS valideert ze tegen gekoppelde schema's vóór evaluatie:
// Benoemde parameter benaderen
meta.params.lang // "ko"
meta.params.country // "us"
meta.params.slug // "welcome-post"
// Controleren of parameter bestaat
has(meta.params.category) // true/false
// Gebruiken in documentopvraag
documents.get("greeting", meta.params.lang)
documents.ref("airports").get(meta.params.code)
Ruwe URL-segmenten als array:
// Benader op index (0-based)
meta.segments[0] // Eerste segment
meta.segments[1] // Tweede segment
// Lengte controleren
size(meta.segments) // Aantal segmenten
// Lidmaatschap controleren
"products" in meta.segments // Bevat het pad "products"?
De UUID van het huidige document, handig voor zelfverwijzende scripts:
// Alleen beschikbaar bij het bewerken van bestaande documenten
meta.docId != null ? "bewerken" : "nieuw aanmaken"
// Gebruik in conditionele logica
meta.docId != null ? documents.get("article", meta.docId).status : "draft"
De titel van het huidige document:
// Gebruik voor weergave
"Bewerken: " + meta.title
// Conditie op basis van titel
meta.title.contains("Draft") ? "werk in uitvoering" : "gepubliceerd"
Voor leesbaardere syntaxis wanneer het schema bekend is maar de identifier dynamisch:
// Traditionele aanpak
documents.get("airports", meta.params.code).name
// Met ref() - schema apart van dynamische identifier
documents.ref("airports").get(meta.params.code).name
Beide zijn gelijkwaardig, maar ref() maakt het dynamische deel duidelijker.
documents.get("schema", "identifier") // Eén document ophalen
documents.get("schema", "id").fieldName // Een specifiek veld ophalen
documents.find("schema") // Alle documenten ophalen
documents.find("schema", { "where": {...}}) // Gefilterde query
documents.ref("schema").get(identifier) // Gekoppelde lookup
documents.translated("schema", "id", "fr") // Ophalen met expliciete locale
meta.locale // "en-US", "ar-SA", enz.
meta.params.xyz // URL-parameter met naam "xyz"
meta.segments // URL-pad als array: ["articles", "intro"]
meta.segments[0] // Eerste padsegment
meta.docId // Huidige document-ID (of null)
meta.title // Huidige documenttitel
doc.fieldName // Veldwaarde van het huidige document (in editorcontext)
// Vergelijking
== != < <= > >=
// Logica
&& || !
// Ternair (if-else)
voorwaarde ? waardeIndienWaar : waardeIndienOnwaar
// Lidmaatschap
"value" in listOrMap
size(list) // Aantal items
size(string) // Stringlengte
"text".startsWith("te") // true
"text".endsWith("xt") // true
"text".contains("ex") // true
has(object.property) // Controleren of eigenschap bestaat
hasProperty(obj, "key") // Controleren of object sleutel heeft (alternatieve syntaxis)
Als er iets misgaat, zie je een van deze meldingen:
| Fout | Betekenis |
|---|---|
SYNTAX_ERROR | Typfout in je script (ontbrekend aanhalingsteken, verkeerde operator) |
TYPE_ERROR | Je combineert typen die niet op elkaar passen |
RUNTIME_ERROR | Het script draaide, maar liep tegen een probleem aan (ongedefinieerde variabele) |
FETCH_LIMIT_EXCEEDED | Je haalt te veel documenten op (max. 50) |
TIMEOUT | Script duurde te lang (max. 5 seconden) |
AST_DEPTH_EXCEEDED | Expressie te diep genest (maximale diepte: 50) |
SCRIPT_TOO_LONG | Script overschrijdt limiet van 5000 tekens |
De CEL-engine is ontworpen voor uitbreidbaarheid. Toekomstige mogelijkheden omvatten:
// Toekomst: externe services aanroepen via MCP
mcp.translate(meta.params.text, "en", meta.params.lang)
mcp.analyze(documents.get("article", meta.params.id).body)
// Toekomst: door AI aangestuurde contentgeneratie
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"])
Deze mogelijkheden worden toegevoegd via het systeem met geregistreerde functies, waarbij achterwaartse compatibiliteit behouden blijft.
documents. of meta. en de editor toont beschikbare optiesdocuments.get("schema", "id") en voeg daarna .fieldName toe!= null ? ... : ...documents.get() of documents.find() telt mee voor de limiet van 50has(meta.params.category) voordat je deze gebruiktDeze sectie behandelt geavanceerde patronen om documenten aan elkaar te koppelen en relationele contentstructuren te bouwen.
De eenvoudigste vorm: één document verwijst naar een ander via een identifier.
// Artikel slaat auteur-ID op, haal naam van auteur op
documents.get("author", documents.get("article", "intro").authorId).name
Voor duidelijkere syntaxis wanneer de identifier dynamisch is:
// Traditionele aanpak
documents.get("country", documents.get("airport", meta.params.code).countryCode).name
// Met ref() - duidelijker wanneer schema bekend is maar identifier dynamisch
\ndocuments.ref("country").get(documents.get("airport", meta.params.code).countryCode).name
Bouw diepgaande relaties door meerdere lookups te koppelen:
// Airport → Country → Region → Continent
documents.get("continent",
documents.get("region",
documents.get("country",
documents.get("airport", meta.params.code).countryCode
).regionCode
).continentCode
).name
Combineer documentverwijzingen met vertalingen:
// Gelokaliseerde landnaam voor een luchthaven ophalen
documents.translated("country",
documents.get("airport", meta.params.code).countryCode,
meta.params.lang
).name
Document slaat een ID op dat naar een ander document verwijst.
// article / tech-news
{ "title": "Tech-update", "authorId": "author-123", "categoryId": "cat-tech" }
// Naam van auteur ophalen
documents.get("author", documents.get("article", meta.params.slug).authorId).name
// Categorie ophalen met fallback
documents.get("article", meta.params.slug).categoryId != null
? documents.get("category", documents.get("article", meta.params.slug).categoryId).name
: "Geen categorie"
Documenten verwijzen naar elkaar via semantische codes in plaats van UUID's.
// airport / JFK
{ "code": "JFK", "name": "John F. Kennedy International", "countryCode": "us" }
// country / us
{ "code": "us", "name": "Verenigde Staten", "currencyCode": "usd" }
// currency / usd
{ "code": "usd", "symbol": "$", "name": "Amerikaanse dollar" }
// Airport → Country → Currency-keten
documents.get("currency",
documents.get("country",
documents.get("airport", meta.params.code).countryCode
).currencyCode
).symbol
// Voor JFK: geeft "$"
Gebruik doc voor berekende velden die andere documenten ophalen op basis van de waarden van het huidige document.
// In een productdocument, haal gerelateerde categoriedetails op
documents.get("category", doc.categoryId).description
// Berekende verzendkosten op basis van herkomstland van product
documents.get("shipping-rates", doc.originCountry).baseRate * doc.weight
Wanneer documenten naar elkaar verwijzen, let op het aantal opvragingen.
// Haal auteur van artikel op en daarna andere artikelen van dezelfde auteur (let op fetch-telling)
documents.find("article", { "where": { "authorId": documents.get("article", meta.params.slug).authorId } })
Wanneer een veld naar verschillende schema's kan verwijzen:
// content-block / hero-1
{ "type": "hero", "sourceType": "article", "sourceId": "welcome-post" }
// content-block / hero-2
{ "type": "hero", "sourceType": "product", "sourceId": "featured-item" }
// Dynamische schema-opvraging op basis van 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
Elke documents.get(), documents.find() en documents.ref().get()-aanroep wordt gevolgd voor cache-invalidatie. Wanneer een verwezen document verandert, weet het CMS welke CEL-expressies opnieuw geëvalueerd moeten worden.
Bijgehouden afhankelijkheden omvatten:
schema:identifier - Specifieke documentafhankelijkheidschema:identifier - Zelfde als get, via gekoppelde syntaxisschema:* - Schema-afhankelijkheid (elk document in het schema)// Slecht: haalt hetzelfde document twee keer op
documents.get("author", documents.get("article", "intro").authorId).name + " - " +
documents.get("author", documents.get("article", "intro").authorId).bio
// Beter: gebruik conditionele controle om slechts één keer te halen
documents.get("article", "intro").authorId != null
? documents.get("author", documents.get("article", "intro").authorId).name
: "Onbekende auteur"
Deze walkthrough maakt een meertalige landing page beschikbaar op /{lang}/landingPage.
Maak in de CMS-beheeromgeving een aangepast schema met de naam greeting:
{
"name": "greeting",
"fields": [
{ "name": "code", "type": "string", "required": true },
{ "name": "headline", "type": "string", "required": true },
{ "name": "subheadline", "type": "string" },
{ "name": "ctaText", "type": "string" },
{ "name": "ctaUrl", "type": "string" }
]
}
Maak documenten voor elke taal:
Document: greeting/ko
{
"code": "ko",
"headline": "Welkom",
"subheadline": "Welkom op ons platform",
"ctaText": "Aan de slag",
"ctaUrl": "/ko/get-started"
}
Document: greeting/en
{
"code": "en",
"headline": "Welkom",
"subheadline": "Welkom op ons platform",
"ctaText": "Aan de slag",
"ctaUrl": "/en/get-started"
}
Document: greeting/ja
{
"code": "ja",
"headline": "Welkom",
"subheadline": "Welkom op ons platform",
"ctaText": "Start",
"ctaUrl": "/ja/get-started"
}
Maak een pagina met de volgende configuratie:
/{lang}/landingPagelang → de component language {
"lang": "language"
}
Voeg een hero-blok toe aan de route met deze CEL-scripts per veld:
Headline-veld:
documents.get("greeting", meta.params.lang).headline
Subheadline-veld:
documents.get("greeting", meta.params.lang).subheadline
CTA-tekstveld:
documents.get("greeting", meta.params.lang).ctaText
CTA-URL-veld:
documents.get("greeting", meta.params.lang).ctaUrl
Voeg een catch-all route toe. ParametricRoutePage lost de pagina op, haalt meta.params uit de URL, evalueert je CEL-koppelingen server-side en rendert elk blok via je registry — je hoeft de meta-context of de low-level client niet zelf te bouwen.
// app/[...slug]/page.tsx
import ParametricRoutePage from 'cms-renderer/lib/renderer';
import { registry } from '@/lib/registry';
import { cmsConfig } from '@/lib/cms-config';
export const dynamic = 'force-static';
interface PageProps {
params: Promise<{ slug: string[] }>;
}
export default async function Page({ params }: PageProps) {
const { slug } = await params;
return (
<ParametricRoutePage
registry={registry}
apiKey={cmsConfig.apiKey}
websiteId={cmsConfig.websiteId}
cmsUrl={cmsConfig.cmsUrl}
params={Promise.resolve({ slug })}
/>
);
}
Bezoek deze URL's om gelokaliseerde inhoud te zien:
| URL | Verwachte headline |
|---|---|
/ko/landingPage | 환영 |
/en/landingPage | Welcome |
/ja/landingPage | いらっしゃいませ |
Wanneer een gebruiker /ko/landingPage bezoekt:
/{lang}/landingPagemeta.params.lang = "ko"languagedocuments.get("greeting", meta.params.lang) leveren Koreaanse content opinterface CelMeta {
/** Huidige localecode (bijv. 'en-US') */
locale: string;
/** Routeparameters die uit de URL zijn gehaald */
params: Record<string, string>;
/** URL-padsegmenten */
segments: string[];
/** Huidige document-ID (bij bewerken bestaand document) */
docId: string | null;
/** Huidige documenttitel */
title: string;
}
De functie extractParams verwerkt URL-paden:
Patroon: /{country}/{lang}/products
Pad: /us/en/products
Algoritme:
1. Normaliseer beide (verwijder afsluitende slashes)
2. Splits in segmenten: ["us", "en", "products"] en ["{country}", "{lang}", "products"]
3. Segmentaantal moet overeenkomen
4. Voor elk segmentpaar:
- Als patroon begint met : of {}, extraheer als parameter
- Anders moet het exact overeenkomen
5. Resultaat: { country: "us", lang: "en" }
// Eenvoudige koppeling (gebruikt veld "code" voor lookup)
{ "lang": "language" }
// Gedetailleerde koppeling (aangepast slug-veld)
{
"lang": {
"schemaName": "language",
"slugField": "code"
},
"slug": {
"schemaName": "article",
"slugField": "slug"
}
}
Bij het ophalen via documents.get(schema, identifier):
idcontent.codecontent.slugtitleZo kun je documenten flexibel refereren met elke unieke identifier.