profound-logoProfound CMS
⌘K
Admin
Theme
DocsTutorialBlogPhilosophy
DocsTutorialBlogPhilosophy

Hybrid

Collection of Pages with ComponentsKomponenttyperSetup server sent events (SSE) content refetchInstall Profound CMS as a proxyScripting i skabelonbyggerenProject ScaffoldingMediebibliotek

Headless

HurtigstartSplit Screen JSON Component Builder with LLMComponent Zod Pull

REST API

REST API-oversigtgetConnect your websitegetGET /routesgetGET /routegetGET /blocksgetGET /blocks/with-cel-cachegetGET /blocks/generatedgetGET /componentsgetGET /components/{name}getGET /dataset/{schema_name}getGET /content-changes (SSE)patchPATCH /dataset/{schema_name}postPOST /translationpatchPATCH /translationsgetGET /usagepostPOST /csvpatchPATCH /csv
All Systems Operational
Powered Byprofound-logo
Theme

Scripting i skabelonbyggeren

En praktisk vejledning til at skrive CEL-udtryk i CMS'et.

En praktisk vejledning til at skrive CEL-udtryk i CMS'et.


Sådan fungerer CEL

CEL (Common Expression Language) er et let scriptingsprog, der er indbygget i vores CMS. Det lader dig skrive dynamiske udtryk, som kan hente data fra dokumenter, læse URL-parametre og beregne værdier dynamisk.

Dette sker, når et CEL-script køres:

Dit script                     Motoren                        Resultat
    |                              |                              |
    v                              v                              v
documents.get("article", "intro") --> Henter fra databasen --> { headline: "Welcome", body: "..." }
         .headline                --> Udtrækker feltet     --> "Welcome"

Tænk på CEL som et skrivebeskyttet forespørgselssprog. Det kan ikke ændre noget i databasen – det læser kun data og returnerer et beregnet resultat. Derfor er det sikkert at bruge overalt i CMS'et.


Byggeklodserne

Alle CEL-udtryk har adgang til tre ting:

ObjektHvad det erEksempel
documentsHent et hvilket som helst dokument fra CMS'etdocuments.get("country", "us")
metaOplysninger om den aktuelle forespørgsel (sprog, URL-parametre)meta.locale, meta.params.slug
schemaFeltd definitionerne for det aktuelle dokumentschema.fields

Selvreferencer med doc

Når du skriver CEL-udtryk i en dokumenteditor, kan du få adgang til det aktuelle dokuments feltværdier via objektet doc. Det muliggør beregnede felter og referencer på tværs af felter.

// Hent det aktuelle dokuments prisfelt
doc.price

// Beregn totalen ud fra det aktuelle dokuments felter
doc.price * doc.quantity

// Betingelse baseret på det aktuelle dokuments status
doc.status == "published" ? doc.title : "Udkast: " + doc.title

Objektet doc indeholder alle feltværdier fra det redigerede dokument. Det er nyttigt til:

  • Beregnede felter (f.eks. doc.price * doc.quantity)
  • Betinget visningslogik baseret på dokumentets tilstand
  • Udtryk af valideringstypen

Hentning af dokumenter

CEL's mest effektive funktion er at hente dokumenter fra hvor som helst i dit CMS.

Hentning af ét dokument

Syntaks: documents.get(schemaName, identifier)

Lad os sige, at du har et article-dokument gemt med identifikatoren "welcome-post":

// Gemt i CMS'et som: article / welcome-post
{
  "headline": "Welcome to Our Platform",
  "author": "Sarah Chen",
  "body": "We're excited to announce...",
  "tags": ["announcement", "news"]
}

Sådan henter du hele dokumentet:

documents.get("article", "welcome-post")

Returnerer:

{
  "headline": "Welcome to Our Platform",
  "author": "Sarah Chen",
  "body": "We're excited to announce...",
  "tags": ["announcement", "news"]
}

Sådan henter du kun overskriften:

documents.get("article", "welcome-post").headline

Returnerer: "Welcome to Our Platform"

Sådan henter du forfatteren:

documents.get("article", "welcome-post").author

Returnerer: "Sarah Chen"


Brug af URL-parametre

Når din side har dynamiske ruter (som /articles/[slug]), kan du bruge meta.params til at hente URL-parameteren og finde det rigtige dokument.

Hvis nogen besøger /articles/welcome-post:

documents.get("article", meta.params.slug).headline

Returnerer: "Welcome to Our Platform"

Sådan bygger du dynamiske sider – det samme CEL-script fungerer for alle artikler og bruger blot den slug, der står i URL'en.


Hentning af flere dokumenter

Syntaks: documents.find(schemaName) eller documents.find(schemaName, filter)

// Hent alle lande
documents.find("country")

Returnerer:

[
  { "code": "us", "name": "United States", "flag": "US" },
  { "code": "sa", "name": "Saudi Arabia", "flag": "SA" },
  { "code": "gb", "name": "United Kingdom", "flag": "GB" }
]
// Hent lande med et filter
documents.find("country", { "where": { "code": "us" } })

Returnerer:

[
  { "code": "us", "name": "United States", "flag": "US" }
]

Oversættelser

CEL understøtter hentning af oversat dokumentindhold på to måder: automatisk oversættelse baseret på sprog og eksplicit opslag af oversættelser.

Automatisk oversættelse via meta.locale

Når meta.locale er angivet (f.eks. fra ruteparametre eller brugerindstillinger), sammenfletter documents.get() automatisk det oversatte indhold:

// Hvis meta.locale er "fr", returneres den franske oversættelse sammenflettet med basedokumentet
documents.get("greeting", "welcome").headline

Sådan fungerer det:

  1. Henter basedokumentets indhold
  2. Hvis meta.locale ikke er "en" eller "en-US", slås oversættelsen op i tabellen translations
  3. De oversatte felter sammenflettes oven på basisindholdet: { ...baseContent, ...translatedContent }

Det betyder, at oversatte felter tilsidesætter basisfelterne, mens ikke-oversatte felter falder tilbage til basedokumentet.

Eksplicit oversættelse med documents.translated()

Hvis du skal hente en bestemt oversættelse uanset det aktuelle sprog:

Syntaks: documents.translated(schemaName, identifier, locale)

// Hent altid den spanske oversættelse
documents.translated("greeting", "welcome", "es").headline

// Hent en oversættelse baseret på en URL-parameter
documents.translated("product", meta.params.id, meta.params.lang).description

// Sammenlign oversættelser
documents.translated("article", "intro", "en").title + " / " + documents.translated("article", "intro", "fr").title

Eksempel på oversættelse

Dine greeting-dokumenter med oversættelser:

// Basedokument: greeting / welcome
{ "headline": "Welcome", "subheadline": "Welcome to our platform" }

// Oversættelse (sprog: "fr")
{ "headline": "Bienvenue", "subheadline": "Bienvenue sur notre plateforme" }

// Oversættelse (sprog: "es")
{ "headline": "Bienvenido", "subheadline": "Bienvenido a nuestra plataforma" }

CEL-scripts:

// Med meta.locale = "fr"
documents.get("greeting", "welcome").headline
// Returnerer: "Bienvenue"

// Eksplicit spansk oversættelse
documents.translated("greeting", "welcome", "es").headline
// Returnerer: "Bienvenido"

// Fallback-mønster ved manglende oversættelser
documents.translated("greeting", "welcome", meta.params.lang) != null
  ? documents.translated("greeting", "welcome", meta.params.lang).headline
  : documents.get("greeting", "welcome").headline

Eksempler fra den virkelige verden

Eksempel 1: Titel på en hero-blok fra et andet dokument

Du har en hero-block, der skal vise en overskrift hentet fra et article-dokument.

Dit article-dokument (identifikator: "homepage-hero"):

{
  "headline": "Build Faster, Ship Smarter",
  "subheadline": "The modern CMS for developers"
}

CEL-script i hero-blokkens titelfelt:

documents.get("article", "homepage-hero").headline

Resultat: Heroen viser "Build Faster, Ship Smarter"


Eksempel 2: Landenavn ud fra kode

Du bygger en side på /countries/[code] og vil vise det fulde landenavn.

Dine landedokumenter:

// country / us
{ "code": "us", "name": "United States", "flag": "US", "languages": ["en", "es"] }

// country / sa
{ "code": "sa", "name": "Saudi Arabia", "flag": "SA", "languages": ["ar", "en"] }

CEL-script:

documents.get("country", meta.params.code).name

Når nogen besøger /countries/us:

  • meta.params.code = "us"
  • Resultat: "United States"

Når nogen besøger /countries/sa:

  • meta.params.code = "sa"
  • Resultat: "Saudi Arabia"

Eksempel 3: Betinget indhold baseret på sprog

Vis forskellige overskrifter baseret på brugerens sprog.

meta.locale == "ar-SA" ? "Welcome, everyone" : "Welcome"

Hvis sproget er "ar-SA": Returnerer "Welcome, everyone" Hvis sproget er noget andet: Returnerer "Welcome"


Eksempel 4: Kædede opslag af dokumenter

Dit article har et felt med navnet countryCode, og du vil hente det fulde landenavn.

Article-dokument:

{ "headline": "News from the US", "countryCode": "us" }

CEL-script:

documents.get("country", documents.get("article", "us-news").countryCode).name

Dette sker:

  1. documents.get("article", "us-news") returnerer { "headline": "News from the US", "countryCode": "us" }
  2. .countryCode udtrækker "us"
  3. documents.get("country", "us") returnerer { "code": "us", "name": "United States", ... }
  4. .name udtrækker "United States"

Resultat: "United States"


Eksempel 5: Fallback-værdier

Hvis et dokument muligvis ikke findes, kan du angive en fallback:

documents.get("article", meta.params.slug) != null
  ? documents.get("article", meta.params.slug).headline
  : "Article Not Found"

Eller kontrollere, om et bestemt felt findes:

documents.get("article", "intro").author != null
  ? documents.get("article", "intro").author
  : "Unknown Author"

Eksempel 6: Arbejde med lister

Din artikel har tags, og du vil kontrollere, om et bestemt tag findes:

"featured" in documents.get("article", "welcome-post").tags

Returnerer: true, hvis artiklen har tagget "featured"

Hent det første tag:

documents.get("article", "welcome-post").tags[0]

Returnerer: "announcement" (det første tag)

Tæl tags:

size(documents.get("article", "welcome-post").tags)

Returnerer: 2 (antal tags)


Parametriske ruter og meta.params

Parametriske ruter er nøglen til at bygge dynamiske, lokaliserede sider. Når du definerer et rutemønster som /{lang}/landingPage, udtrækker CMS'et parametre fra URL'en og gør dem tilgængelige via meta.params.

Sådan fungerer ruteparametre

Definition af rutemønster: Ruter bruger syntaksen :paramName eller {paramName} til at definere dynamiske segmenter:

MønsterEksempel-URLUdtrukne parametre
/:lang/landingPage/ko/landingPage{ lang: "ko" }
/{country}/{lang}/products/us/en/products{ country: "us", lang: "en" }
/articles/:slug/articles/welcome-post{ slug: "welcome-post" }

Parameterbindinger: Hver ruteparameter kan bindes til et dokumentskema til validering:

{
  "pattern": "/{lang}/landingPage",
  "param_bindings": {
    "lang": "language"
  }
}

Bindingen fortæller CMS'et:

  1. Udtræk segmentet lang fra URL'en
  2. Validér det mod language-skemaet (find et dokument, hvor content.code matcher)
  3. Hvis det er gyldigt, gøres hele dokumentet tilgængeligt i de opløste parametre

Eksempel: Sprogbaseret landingsside

Rutef konfiguration:

  • Sti: /{lang}/landingPage
  • Mønster: /{lang}/landingPage
  • Parameterbindinger: { "lang": "language" }

Dine greeting-dokumenter:

// greeting / ko
{ "code": "ko", "headline": "Welcome", "subheadline": "Welcome to our platform", "ctaText": "Get Started", "ctaUrl": "/ko/get-started" }

// greeting / en
{ "code": "en", "headline": "Welcome", "subheadline": "Welcome to our platform", "ctaText": "Get Started", "ctaUrl": "/en/get-started" }

// greeting / ja
{ "code": "ja", "headline": "Welcome", "subheadline": "Welcome to our platform", "ctaText": "Start", "ctaUrl": "/ja/get-started" }

CEL-script til hentning af lokaliseret indhold:

documents.get("greeting", meta.params.lang).headline

Sådan opløses det:

URLmeta.params.langResultat
/ko/landingPage"ko""Welcome"
/en/landingPage"en""Welcome"
/ja/landingPage"ja""Welcome"

Avanceret mønster: Ruter med land og sprog

For ruter som /{country}/{lang}/products:

Rutef konfiguration:

{
  "pattern": "/{country}/{lang}/products",
  "param_bindings": {
    "country": "country",
    "lang": "language"
  }
}

CEL-scripts:

// Hent landenavn
documents.get("country", meta.params.country).name

// Hent en lokaliseret produktliste baseret på land
documents.find("product", { "where": { "country": meta.params.country } })

// Kombineret: Vis en landespecifik hilsen på brugerens sprog
documents.get("greeting", meta.params.lang).headline + " from " + documents.get("country", meta.params.country).name

Valideringskaskade: CMS'et validerer parametre hierarkisk. For ruter af typen /{country}/{lang}:

  1. Validerer parameteren country mod skemaet country
  2. Validerer parameteren lang mod skemaet language
  3. Validerer eventuelt, at lang findes i arrayet country.languages[] (hierarkisk validering)

meta.segments – adgang til rå URL-sti

meta.segments leverer den rå URL-sti som et array og er nyttig, når du har brug for positionsbaseret adgang uden navngivne parametre.

Sådan fungerer det:

URL-stimeta.segments
/articles/tech/ai-news["articles", "tech", "ai-news"]
/ko/landingPage["ko", "landingPage"]
/us/en/products/featured["us", "en", "products", "featured"]
/[]

Hvornår skal meta.segments bruges frem for meta.params?

AnvendelseBedste tilgang
Navngivne parametre fra rutemønsteretmeta.params.lang
Positionsbaseret adgangmeta.segments[0]
Hentning af stidybdesize(meta.segments)
Kontrol af, om stien indeholder et segment"admin" in meta.segments

Eksempler med meta.segments

// Hent det første segment (ofte en sprogkode)
meta.segments[0]

// Kontrollér stidybden
size(meta.segments) > 2 ? "deep" : "shallow"

// Kontrollér, om vi er i administrationssektionen
"admin" in meta.segments ? "admin mode" : "public mode"

// Fallback: Brug segmentet, hvis parameteren ikke er bundet
has(meta.params.lang) ? meta.params.lang : meta.segments[0]

Komplet reference til meta-objektet

Objektet meta indeholder hele konteksten for den aktuelle forespørgsel:

EgenskabTypeBeskrivelse
meta.localestringAktuel sprogkode (f.eks. "en-US", "ko-KR", "ar-SA")
meta.paramsRecord<string, string>Ruteparametre udtrukket fra URL-mønsteret
meta.segmentsstring[]URL-stien opdelt i segmenter
meta.docId`string \null`Det aktuelle dokuments UUID (null for nye dokumenter)
meta.titlestringDet aktuelle dokuments titel

meta.locale

Sprogkoden følger BCP 47-formatet (sprog-region):

// Kontrollér sprog for RTL-sprog
meta.locale == "ar-SA" || meta.locale == "he-IL" ? "rtl" : "ltr"

// Hent kun sprogdelen
meta.locale.split("-")[0]  // Ikke understøttet – brug i stedet meta.params.lang

meta.params

Ruteparametre er altid strenge. CMS'et validerer dem mod bundne skemaer før evaluering:

// Få adgang til en navngiven parameter
meta.params.lang           // "ko"
meta.params.country        // "us"
meta.params.slug           // "welcome-post"

// Kontrollér, om en parameter findes
has(meta.params.category)  // true/false

// Brug den i en dokumenthentning
documents.get("greeting", meta.params.lang)
documents.ref("airports").get(meta.params.code)

meta.segments

Rå URL-segmenter som et array:

// Få adgang via indeks (0-baseret)
meta.segments[0]           // Første segment
meta.segments[1]           // Andet segment

// Kontrollér længden
size(meta.segments)        // Antal segmenter

// Kontrollér medlemskab
"products" in meta.segments  // Indeholder stien "products"?

meta.docId

Det aktuelle dokuments UUID, nyttigt til selvrefererende scripts:

// Kun tilgængelig ved redigering af eksisterende dokumenter
meta.docId != null ? "editing" : "creating new"

// Brug i betinget logik
meta.docId != null ? documents.get("article", meta.docId).status : "draft"

meta.title

Titlen på det aktuelle dokument:

// Brug til visning
"Editing: " + meta.title

// Betingelse baseret på titlen
meta.title.contains("Draft") ? "work in progress" : "published"

documents.ref() – kædede opslag

For en renere syntaks, når skemaet er kendt, men identifikatoren er dynamisk:

// Traditionel tilgang
documents.get("airports", meta.params.code).name

// Brug af ref() – skemaet er adskilt fra den dynamiske identifikator
documents.ref("airports").get(meta.params.code).name

Begge metoder er ækvivalente, men ref() gør den dynamiske del tydeligere.


Hurtig reference

Dokumenthentning

documents.get("schema", "identifier")       // Hent ét dokument
documents.get("schema", "id").fieldName     // Hent et bestemt felt
documents.find("schema")                    // Hent alle dokumenter
documents.find("schema", { "where": {...}}) // Filtreret forespørgsel
documents.ref("schema").get(identifier)     // Kædet opslag
documents.translated("schema", "id", "fr")  // Hent med eksplicit sprog

Kontekstvariabler

meta.locale          // "en-US", "ar-SA" osv.
meta.params.xyz      // URL-parameter med navnet "xyz"
meta.segments        // URL-sti som array: ["articles", "intro"]
meta.segments[0]     // Første stisegment
meta.docId           // Aktuelt dokument-id (eller null)
meta.title           // Aktuel dokumenttitel
doc.fieldName        // Værdien af det aktuelle dokuments felt (i redigeringskontekst)

Operatorer

// Sammenligning
==  !=  <  <=  >  >=

// Logik
&&  ||  !

// Ternær (hvis-ellers)
betingelse ? værdiHvisSand : værdiHvisFalsk

// Medlemskab
"value" in listOrMap

Almindelige funktioner

size(list)                    // Tæl elementer
size(string)                  // Strenglængde
"text".startsWith("te")       // true
"text".endsWith("xt")         // true
"text".contains("ex")         // true
has(object.property)          // Kontrollér, om egenskaben findes
hasProperty(obj, "key")       // Kontrollér, om objektet har nøglen (alternativ syntaks)

Fejlmeddelelser

Hvis noget går galt, får du vist en af disse fejl:

FejlHvad den betyder
SYNTAX_ERRORTypo i dit script (manglende citationstegn eller ugyldig operator)
TYPE_ERRORDu blander typer, der ikke kan bruges sammen
RUNTIME_ERRORScriptet blev kørt, men stødte på et problem (udefineret variabel)
FETCH_LIMIT_EXCEEDEDDu henter for mange dokumenter (maks. 50)
TIMEOUTScriptet tog for lang tid (maks. 5 sekunder)
AST_DEPTH_EXCEEDEDUdtrykket er indlejret for dybt (maks. dybde: 50)
SCRIPT_TOO_LONGScriptet overskrider grænsen på 5000 tegn

Udvidelsesmuligheder og fremtidige funktioner

CEL-motoren er designet til at kunne udvides. Planlagte fremtidige funktioner omfatter:

Planlagt: MCP-serverintegration

// Fremtid: Kald eksterne tjenester via MCP
mcp.translate(meta.params.text, "en", meta.params.lang)
mcp.analyze(documents.get("article", meta.params.id).body)

Planlagt: AI-funktioner

// Fremtid: AI-baseret indholdsgenerering
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"])

Disse funktioner tilføjes via det registrerede funktionssystem, så bagudkompatibiliteten med eksisterende scripts bevares.


Tips

  1. Brug autofuldførelse – Skriv documents. eller meta., så viser editoren de tilgængelige muligheder
  2. Begynd enkelt – Test først med documents.get("schema", "id"), og tilføj derefter .fieldName
  3. Kontrollér for null – Hvis et dokument muligvis ikke findes, kan du tilføje en fallback med != null ? ... : ...
  4. Hent ikke for meget – Hvert documents.get()- eller documents.find()-kald tæller mod grænsen på 50 hentninger
  5. Foretræk meta.params frem for meta.segments – Navngivne parametre valideres og er mere pålidelige
  6. Brug has() til valgfrie parametre – Kontrollér has(meta.params.category), før du tilgår parameteren
  7. Brug documents.ref() til dynamiske identifikatorer – Tydeligere syntaks, når skemaet er statisk, men identifikatoren dynamisk
  8. Brug doc.fieldName til selvreferencer – Få adgang til det aktuelle dokuments felter i beregnede udtryk

Referencer fra dokument til dokument

Dette afsnit beskriver avancerede mønstre til at forbinde dokumenter og opbygge relationelle indholdsstrukturer.

Grundlæggende referencemønster

Den enkleste form: Ét dokument refererer til et andet via dets identifikator.

// Artiklen gemmer forfatterens id; hent forfatterens navn
documents.get("author", documents.get("article", "intro").authorId).name

Kædede opslag med documents.ref()

Når identifikatoren er dynamisk, giver denne syntaks et renere udtryk:

// Traditionel tilgang
documents.get("country", documents.get("airport", meta.params.code).countryCode).name

// Brug af ref() – tydeligere, når skemaet er kendt, men identifikatoren er dynamisk
documents.ref("country").get(documents.get("airport", meta.params.code).countryCode).name

Referencer på flere niveauer

Opbyg dybe relationer ved at kæde flere opslag sammen:

// Lufthavn → Land → Region → Kontinent
documents.get("continent",
  documents.get("region",
    documents.get("country",
      documents.get("airport", meta.params.code).countryCode
    ).regionCode
  ).continentCode
).name

Reference med oversættelse

Kombinér dokumentreferencer med oversættelser:

// Hent lokaliseret landenavn for en lufthavn
documents.translated("country",
  documents.get("airport", meta.params.code).countryCode,
  meta.params.lang
).name

Referencemønstre efter anvendelse

Mønster 1: Opslag med fremmednøgle

Dokumentet gemmer et id, der refererer til et andet dokument.

// article / tech-news
{ "title": "Tech Update", "authorId": "author-123", "categoryId": "cat-tech" }
// Opløs forfatterens navn
documents.get("author", documents.get("article", meta.params.slug).authorId).name

// Opløs kategori med fallback
documents.get("article", meta.params.slug).categoryId != null
  ? documents.get("category", documents.get("article", meta.params.slug).categoryId).name
  : "Uncategorized"

Mønster 2: Kodebaserede referencer

Dokumenter refererer til hinanden via semantiske koder i stedet for UUID'er.

// airport / JFK
{ "code": "JFK", "name": "John F. Kennedy International", "countryCode": "us" }

// country / us
{ "code": "us", "name": "United States", "currencyCode": "usd" }

// currency / usd
{ "code": "usd", "symbol": "$", "name": "US Dollar" }
// Kæde: Lufthavn → Land → Valuta
documents.get("currency",
  documents.get("country",
    documents.get("airport", meta.params.code).countryCode
  ).currencyCode
).symbol
// For JFK: Returnerer "$"

Mønster 3: Selvreference med doc-kontekst

Brug doc til beregnede felter, der refererer til andre dokumenter ud fra det aktuelle dokuments værdier.

// Hent relaterede kategoridetaljer i et produktdokument
documents.get("category", doc.categoryId).description

// Beregnet fragtpris baseret på produktets oprindelsesland
documents.get("shipping-rates", doc.originCountry).baseRate * doc.weight

Mønster 4: Tovejsreferencer

Når dokumenter refererer til hinanden, skal du være opmærksom på grænsen for hentninger.

// Hent artiklens forfatter og derefter forfatterens andre artikler (vær opmærksom på antal hentninger!)
documents.find("article", { "where": { "authorId": documents.get("article", meta.params.slug).authorId } })

Mønster 5: Polymorfe referencer

Når et felt kan referere til forskellige skemaer:

// content-block / hero-1
{ "type": "hero", "sourceType": "article", "sourceId": "welcome-post" }

// content-block / hero-2
{ "type": "hero", "sourceType": "product", "sourceId": "featured-item" }
// Dynamisk skemaopslag baseret på 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

Afhængighedssporing

Alle kald til documents.get(), documents.find() og documents.ref().get() spores med henblik på cache-invalidering. Når et refereret dokument ændres, ved CMS'et, hvilke CEL-udtryk der skal evalueres igen.

Sporrede afhængigheder omfatter:

  • get: schema:identifier – Afhængighed af et bestemt dokument
  • ref: schema:identifier – Det samme som get via kædet syntaks
  • query: schema:* – Afhængighed på skemaniveau (ethvert dokument i skemaet)

Bedste praksis for referencer

  1. Minimér kædedybden – Hvert niveau øger svartid og antal hentninger
  2. Cache mellemresultater – Hvis du skal bruge den samme indlejrede værdi to gange, så hent forælderen én gang
  3. Brug null-kontroller – Referencer kan gå i stykker, hvis dokumenter slettes
  4. Foretræk koder frem for UUID'er – Koder er læsbare i udtryk og stabile på tværs af miljøer
  5. Vær opmærksom på hentningsgrænser – Komplekse referencekæder kan hurtigt nå grænsen på 50 hentninger

Appendiks A: Komplet eksempel på parametrisk rute

Denne gennemgang opretter en flersproget landingsside, der er tilgængelig på /{lang}/landingPage.

Trin 1: Opret skemaet for greeting-dokumentet

Opret et brugerdefineret skema med navnet greeting i CMS-administrationen:

{
  "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" }
  ]
}

Trin 2: Opret greeting-dokumenter

Opret dokumenter for hvert sprog:

Dokument: greeting/ko

{
  "code": "ko",
  "headline": "Welcome",
  "subheadline": "Welcome to our platform",
  "ctaText": "Get Started",
  "ctaUrl": "/ko/get-started"
}

Dokument: greeting/en

{
  "code": "en",
  "headline": "Welcome",
  "subheadline": "Welcome to our platform",
  "ctaText": "Get Started",
  "ctaUrl": "/en/get-started"
}

Dokument: greeting/ja

{
  "code": "ja",
  "headline": "Welcome",
  "subheadline": "Welcome to our platform",
  "ctaText": "Start",
  "ctaUrl": "/ja/get-started"
}

Trin 3: Opret siden

Opret en side med følgende konfiguration:

  • Sti/mønster: /{lang}/landingPage
  • Tilstand: Live
  • Tilknytninger af dynamiske segmenter: tilknyt lang → language-komponenten
  {
    "lang": "language"
  }

Trin 4: Tilføj blokke med CEL-scripts

Tilføj en hero-blok til ruten med disse CEL-scripts for hvert felt:

Feltet Headline:

documents.get("greeting", meta.params.lang).headline

Feltet Subheadline:

documents.get("greeting", meta.params.lang).subheadline

Feltet CTA Text:

documents.get("greeting", meta.params.lang).ctaText

Feltet CTA URL:

documents.get("greeting", meta.params.lang).ctaUrl

Trin 5: Brug i Next.js

Tilføj en catch-all-rute. ParametricRoutePage opløser siden, udtrækker meta.params fra URL'en, evaluerer dine CEL-bindinger på serversiden og renderer hver blok via dit registry – du behøver ikke selv oprette meta-konteksten eller kalde klienten på lavt niveau.

// 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 })}
    />
  );
}

Trin 6: Test ruterne

Besøg disse URL'er for at se lokaliseret indhold:

URLForventet overskrift
/ko/landingPage환영
/en/landingPageWelcome
/ja/landingPageいらっしゃいませ

Sådan fungerer opløsningen

Når en bruger besøger /ko/landingPage:

  1. Rutematchning: CMS'et matcher mønsteret /{lang}/landingPage
  2. Parameterudtrækning: meta.params.lang = "ko"
  3. Validering: CMS'et validerer, at "ko" findes i skemaet language
  4. CEL-evaluering: Scripts som documents.get("greeting", meta.params.lang) opløses til koreansk indhold
  5. Svar: Lokaliserede blokke returneres til klienten

Appendiks B: Teknisk reference

CelMeta-interface (TypeScript)

interface CelMeta {
  /** Aktuel sprogkode (f.eks. 'en-US') */
  locale: string;
  /** Ruteparametre udtrukket fra URL'en */
  params: Record<string, string>;
  /** URL-stisegmenter */
  segments: string[];
  /** Aktuelt dokument-id (hvis et eksisterende dokument redigeres) */
  docId: string | null;
  /** Aktuel dokumenttitel */
  title: string;
}

Algoritme til parameterudtrækning

Funktionen extractParams behandler URL-stier:

Mønster: /{country}/{lang}/products
Sti:     /us/en/products

Algoritme:
1. Normalisér begge (fjern afsluttende skråstreger)
2. Opdel i segmenter: ["us", "en", "products"] og ["{country}", "{lang}", "products"]
3. Match antal segmenter (skal være ens)
4. For hvert segmentpar:
   - Hvis mønsteret begynder med : eller {}, udtrækkes det som parameter
   - Ellers skal det matche nøjagtigt
5. Returnér: { country: "us", lang: "en" }

Understøttede formater for parameterbinding

// Simpel binding (bruger feltet "code" til opslag)
{ "lang": "language" }

// Detaljeret binding (brugerdefineret slug-felt)
{
  "lang": {
    "schemaName": "language",
    "slugField": "code"
  },
  "slug": {
    "schemaName": "article",
    "slugField": "slug"
  }
}

Prioritet for dokumentopslag

Ved hentning via documents.get(schema, identifier):

  1. UUID-match: Hvis identifikatoren er en gyldig UUID, hentes der via id
  2. Code-felt: Kontrollér feltet content.code
  3. Slug-felt: Kontrollér feltet content.slug
  4. Titelmatch: Kontrollér feltet title

Det giver fleksible dokumentreferencer via enhver unik identifikator.

Continue Reading
Previous‹Install Profound CMS as a proxyNextProject Scaffolding›