profound-logoProfound CMS
⌘K
Admin
Theme
DokumentaceTutorialBlogPhilosophy
DokumentaceTutorialBlogPhilosophy

Hybrid

Parametrické směrováníTypes of ComponentsSetup server sent events (SSE) content refetchNastavení proxy administračního paneluCEL Scripting in Template BuilderProject ScaffoldingKnihovna médií

Headless

Rychlý startJson a claude kódComponent Zod Pull

rozhraní REST API

REST API OverviewgetPřipojení webu k API CMSgetGET /routesgetGET /routegetGET /blocksgetzískat bloky s mezipamětí CELgetGET /blocks/generatedgetGET /componentsgetGET /components/{name}getGET /dataset/{schema_name}getGET /content-changes (SSE)patchPATCH /dataset/{schema_name}postPřeklad po publikacipatchPATCH /translationsgetGET /usagepostPOST /csvpatchPATCH /csv
All Systems Operational
Powered Byprofound-logo
Theme

CEL Scripting in Template Builder

Praktická příručka pro psaní výrazů CEL v CMS.

Praktická příručka pro psaní výrazů CEL v CMS.


Jak CEL funguje

CEL (Common Expression Language) je lehký skriptovací jazyk zabudovaný do našeho CMS. Umožňuje psát dynamické výrazy, které mohou načítat data z dokumentů, číst parametry URL a průběžně vypočítávat hodnoty.

Co se stane při spuštění skriptu CEL:

Váš skript                     Modul                          Výsledek
    |                              |                              |
    v                              v                              v
documents.get("article", "intro") --> Načte z databáze --> { headline: "Welcome", body: "..." }
         .headline                --> Extrahuje pole       --> "Welcome"

CEL si můžete představit jako jazyk dotazů pouze pro čtení. Nemůže nic měnit v databázi – pouze čte data a vrací vypočítaný výsledek. Díky tomu je bezpečný pro použití kdekoli v CMS.


Základní stavební prvky

Každý výraz CEL má přístup ke třem věcem:

ObjektCo představujePříklad
documentsNačtení libovolného dokumentu z CMSdocuments.get("country", "us")
metaInformace o aktuálním požadavku (lokalizace, parametry URL)meta.locale, meta.params.slug
schemaDefinice polí aktuálního dokumentuschema.fields

Odkazování na sebe pomocí doc

Při psaní výrazů CEL v editoru dokumentu můžete k hodnotám polí aktuálního dokumentu přistupovat pomocí objektu doc. To umožňuje vypočítávaná pole a odkazy mezi poli.

// Přístup k poli ceny aktuálního dokumentu
doc.price

// Výpočet celkové částky z polí aktuálního dokumentu
doc.price * doc.quantity

// Podmínka založená na stavu aktuálního dokumentu
doc.status == "published" ? doc.title : "Draft: " + doc.title

Objekt doc obsahuje všechny hodnoty polí upravovaného dokumentu. Hodí se pro:

  • Vypočítávaná pole (např. doc.price * doc.quantity)
  • Podmíněnou logiku zobrazení založenou na stavu dokumentu
  • Výrazy ve stylu validace

Načítání dokumentů

Nejvýkonnější funkcí CEL je načítání dokumentů odkudkoli z vašeho CMS.

Získání jednoho dokumentu

Syntaxe: documents.get(schemaName, identifier)

Řekněme, že máte dokument article uložený s identifikátorem "welcome-post":

// Uloženo v CMS jako: article / welcome-post
{
  "headline": "Welcome to Our Platform",
  "author": "Sarah Chen",
  "body": "We're excited to announce...",
  "tags": ["announcement", "news"]
}

Načtení celého dokumentu:

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

Vrátí:

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

Načtení pouze nadpisu:

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

Vrátí: "Welcome to Our Platform"

Načtení autora:

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

Vrátí: "Sarah Chen"


Použití parametrů URL

Když má vaše stránka dynamické routy (například /articles/[slug]), můžete pomocí meta.params získat parametr URL a načíst správný dokument.

Pokud někdo navštíví /articles/welcome-post:

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

Vrátí: "Welcome to Our Platform"

Takto vytváříte dynamické stránky – stejný skript CEL funguje pro jakýkoli článek a použije slug uvedený v URL.


Načítání více dokumentů

Syntaxe: documents.find(schemaName) nebo documents.find(schemaName, filter)

// Získání všech zemí
documents.find("country")

Vrátí:

[
  { "code": "us", "name": "United States", "flag": "US" },
  { "code": "sa", "name": "Saudi Arabia", "flag": "SA" },
  { "code": "gb", "name": "United Kingdom", "flag": "GB" }
]
// Získání zemí s filtrem
documents.find("country", { "where": { "code": "us" } })

Vrátí:

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

Překlady

CEL podporuje načítání přeloženého obsahu dokumentů dvěma způsoby: automatickým překladem podle lokalizace a explicitním vyhledáním překladu.

Automatický překlad pomocí meta.locale

Když je nastaveno meta.locale (například z parametrů routy nebo preferencí uživatele), documents.get() automaticky sloučí přeložený obsah:

// Pokud je meta.locale „fr“, vrátí francouzský překlad sloučený se základním dokumentem
documents.get("greeting", "welcome").headline

Jak to funguje:

  1. Načte obsah základního dokumentu
  2. Pokud meta.locale není „en“ ani „en-US“, vyhledá překlad v tabulce translations
  3. Sloučí přeložená pole přes základní obsah: { ...baseContent, ...translatedContent }

To znamená, že přeložená pole mají přednost před základními poli, zatímco nepřeložená pole se převezmou ze základního dokumentu.

Explicitní překlad pomocí documents.translated()

Pokud potřebujete načíst konkrétní překlad bez ohledu na aktuální lokalizaci:

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

// Vždy načíst španělský překlad
documents.translated("greeting", "welcome", "es").headline

// Načíst překlad podle parametru URL
documents.translated("product", meta.params.id, meta.params.lang).description

// Porovnat překlady
documents.translated("article", "intro", "en").title + " / " + documents.translated("article", "intro", "fr").title

Příklad překladu

Dokumenty s pozdravy a překlady:

// Základní dokument: greeting / welcome
{ "headline": "Welcome", "subheadline": "Welcome to our platform" }

// Překlad (jazyk: "fr")
{ "headline": "Bienvenue", "subheadline": "Bienvenue sur notre plateforme" }

// Překlad (jazyk: "es")
{ "headline": "Bienvenido", "subheadline": "Bienvenido a nuestra plataforma" }

Skripty CEL:

// S meta.locale = "fr"
documents.get("greeting", "welcome").headline
// Vrátí: "Bienvenue"

// Explicitní španělský překlad
documents.translated("greeting", "welcome", "es").headline
// Vrátí: "Bienvenido"

// Vzor pro náhradní hodnotu při chybějícím překladu
documents.translated("greeting", "welcome", meta.params.lang) != null
  ? documents.translated("greeting", "welcome", meta.params.lang).headline
  : documents.get("greeting", "welcome").headline

Příklady z praxe

Příklad 1: Nadpis hero bloku z jiného dokumentu

Máte hero-block, který má zobrazit nadpis načtený z dokumentu article.

Dokument článku (identifikátor: "homepage-hero"):

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

Skript CEL v poli nadpisu hero bloku:

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

Výsledek: Hero zobrazí "Build Faster, Ship Smarter"


Příklad 2: Název země podle kódu

Vytváříte stránku na /countries/[code] a chcete zobrazit celý název země.

Dokumenty zemí:

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

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

Skript CEL:

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

Když někdo navštíví /countries/us:

  • meta.params.code = "us"
  • Výsledek: "United States"

Když někdo navštíví /countries/sa:

  • meta.params.code = "sa"
  • Výsledek: "Saudi Arabia"

Příklad 3: Podmíněný obsah podle lokalizace

Zobrazte různé nadpisy podle lokalizace uživatele.

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

Pokud je lokalizace "ar-SA": Vrátí "Welcome, everyone" Pokud je lokalizace jiná: Vrátí "Welcome"


Příklad 4: Řetězené vyhledávání dokumentů

Váš article má pole countryCode a chcete získat celý název země.

Dokument článku:

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

Skript CEL:

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

Co se stane:

  1. documents.get("article", "us-news") vrátí { "headline": "News from the US", "countryCode": "us" }
  2. .countryCode extrahuje "us"
  3. documents.get("country", "us") vrátí { "code": "us", "name": "United States", ... }
  4. .name extrahuje "United States"

Výsledek: "United States"


Příklad 5: Náhradní hodnoty

Pokud dokument nemusí existovat, můžete zadat náhradní hodnotu:

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

Nebo ověřit, zda existuje konkrétní pole:

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

Příklad 6: Práce se seznamy

Váš článek má štítky a chcete ověřit, zda obsahuje konkrétní štítek:

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

Vrátí: true, pokud článek obsahuje štítek „featured“

Získání prvního štítku:

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

Vrátí: "announcement" (první štítek)

Spočítání štítků:

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

Vrátí: 2 (počet štítků)


Parametrické routy a meta.params

Parametrické routy jsou klíčem k tvorbě dynamických lokalizovaných stránek. Když definujete vzor routy jako /{lang}/landingPage, CMS extrahuje parametry z URL a zpřístupní je prostřednictvím meta.params.

Jak fungují parametry rout

Definice vzoru routy: Routy používají syntaxi :paramName nebo {paramName} pro definování dynamických segmentů:

VzorPříklad URLExtrahované parametry
/:lang/landingPage/ko/landingPage{ lang: "ko" }
/{country}/{lang}/products/us/en/products{ country: "us", lang: "en" }
/articles/:slug/articles/welcome-post{ slug: "welcome-post" }

Vazby parametrů: Každý parametr routy lze pro validaci navázat na schéma dokumentu:

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

Tato vazba CMS říká:

  1. Extrahuj segment lang z URL
  2. Ověř jej proti schématu language (hledej dokument, jehož content.code odpovídá)
  3. Pokud je platný, zpřístupni celý dokument ve vyřešených parametrech

Příklad: Vstupní stránka podle jazyka

Konfigurace routy:

  • Cesta: /{lang}/landingPage
  • Vzor: /{lang}/landingPage
  • Vazby parametrů: { "lang": "language" }

Dokumenty pozdravů:

// 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" }

Skript CEL pro načtení lokalizovaného obsahu:

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

Jak se vyhodnotí:

URLmeta.params.langVýsledek
/ko/landingPage"ko""Welcome"
/en/landingPage"en""Welcome"
/ja/landingPage"ja""Welcome"

Pokročilý vzor: Routy země a jazyka

Pro routy jako /{country}/{lang}/products:

Konfigurace routy:

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

Skripty CEL:

// Získání názvu země
documents.get("country", meta.params.country).name

// Získání lokalizovaného seznamu produktů podle země
documents.find("product", { "where": { "country": meta.params.country } })

// Kombinace: Zobrazení pozdravu specifického pro zemi v jazyce uživatele
documents.get("greeting", meta.params.lang).headline + " from " + documents.get("country", meta.params.country).name

Kaskáda validace: CMS ověřuje parametry hierarchicky. Pro routy /{country}/{lang}:

  1. Ověří parametr country proti schématu country
  2. Ověří parametr lang proti schématu language
  3. Volitelně ověří, že lang je v poli country.languages[] (hierarchická validace)

meta.segments – Přístup k surové cestě URL

meta.segments poskytuje surovou cestu URL jako pole, což je užitečné, když potřebujete poziční přístup bez pojmenovaných parametrů.

Jak to funguje:

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

Kdy použít meta.segments a kdy meta.params

Případ použitíNejvhodnější přístup
Pojmenované parametry ze vzoru routymeta.params.lang
Přístup podle pozicemeta.segments[0]
Zjištění hloubky cestysize(meta.segments)
Ověření, zda cesta obsahuje segment"admin" in meta.segments

Příklady s meta.segments

// Získání prvního segmentu (často kód jazyka)
meta.segments[0]

// Kontrola hloubky cesty
size(meta.segments) > 2 ? "deep" : "shallow"

// Kontrola, zda jsme v administraci
"admin" in meta.segments ? "admin mode" : "public mode"

// Náhradní řešení: Použití segmentu, pokud parametr není navázán
has(meta.params.lang) ? meta.params.lang : meta.segments[0]

Kompletní reference objektu meta

Objekt meta obsahuje veškerý kontext aktuálního požadavku:

VlastnostTypPopis
meta.localestringKód aktuální lokalizace (např. "en-US", "ko-KR", "ar-SA")
meta.paramsRecord<string, string>Parametry routy extrahované ze vzoru URL
meta.segmentsstring[]Cesta URL rozdělená na segmenty
meta.docId`string \null`UUID aktuálního dokumentu (u nových dokumentů null)
meta.titlestringNázev aktuálního dokumentu

meta.locale

Kód lokalizace se řídí formátem BCP 47 (jazyk-oblast):

// Kontrola lokalizace pro jazyky psané zprava doleva
meta.locale == "ar-SA" || meta.locale == "he-IL" ? "rtl" : "ltr"

// Získání pouze části s jazykem
meta.locale.split("-")[0]  // Není podporováno – použijte místo toho meta.params.lang

meta.params

Parametry rout jsou vždy řetězce. CMS je před vyhodnocením ověří proti navázaným schématům:

// Přístup k pojmenovanému parametru
meta.params.lang           // "ko"
meta.params.country        // "us"
meta.params.slug           // "welcome-post"

// Kontrola existence parametru
has(meta.params.category)  // true/false

// Použití při načítání dokumentu
documents.get("greeting", meta.params.lang)
documents.ref("airports").get(meta.params.code)

meta.segments

Surové segmenty URL jako pole:

// Přístup podle indexu (od 0)
meta.segments[0]           // První segment
meta.segments[1]           // Druhý segment

// Kontrola délky
size(meta.segments)        // Počet segmentů

// Kontrola výskytu
"products" in meta.segments  // Obsahuje cesta „products“?

meta.docId

UUID aktuálního dokumentu, užitečné pro skripty odkazující na sebe sama:

// Dostupné pouze při úpravě existujících dokumentů
meta.docId != null ? "editing" : "creating new"

// Použití v podmíněné logice
meta.docId != null ? documents.get("article", meta.docId).status : "draft"

meta.title

Název aktuálního dokumentu:

// Použití pro zobrazení
"Editing: " + meta.title

// Podmínka založená na názvu
meta.title.contains("Draft") ? "work in progress" : "published"

documents.ref() – Řetězené vyhledávání

Pro přehlednější syntaxi, když je schéma známé, ale identifikátor je dynamický:

// Tradiční přístup
documents.get("airports", meta.params.code).name

// Použití ref() – schéma oddělené od dynamického identifikátoru
documents.ref("airports").get(meta.params.code).name

Oba způsoby jsou ekvivalentní, ale ref() zřetelněji odlišuje dynamickou část.


Rychlá reference

Načítání dokumentů

documents.get("schema", "identifier")       // Získá jeden dokument
documents.get("schema", "id").fieldName     // Získá konkrétní pole
documents.find("schema")                    // Získá všechny dokumenty
documents.find("schema", { "where": {...}}) // Filtrovaný dotaz
documents.ref("schema").get(identifier)     // Řetězené vyhledávání
documents.translated("schema", "id", "fr")  // Získá dokument s explicitní lokalizací

Kontextové proměnné

meta.locale          // "en-US", "ar-SA" atd.
meta.params.xyz      // Parametr URL s názvem "xyz"
meta.segments        // Cesta URL jako pole: ["articles", "intro"]
meta.segments[0]     // První segment cesty
meta.docId           // ID aktuálního dokumentu (nebo null)
meta.title           // Název aktuálního dokumentu
doc.fieldName        // Hodnota pole aktuálního dokumentu (v kontextu editoru)

Operátory

// Porovnání
==  !=  <  <=  >  >=

// Logika
&&  ||  !

// Ternární operátor (if-else)
condition ? valueIfTrue : valueIfFalse

// Příslušnost
"value" in listOrMap

Běžné funkce

size(list)                    // Počet položek
size(string)                  // Délka řetězce
"text".startsWith("te")       // true
"text".endsWith("xt")         // true
"text".contains("ex")         // true
has(object.property)          // Kontrola existence vlastnosti
hasProperty(obj, "key")       // Kontrola, zda objekt obsahuje klíč (alternativní syntaxe)

Chybové zprávy

Pokud se něco pokazí, zobrazí se jedna z těchto zpráv:

ChybaVýznam
SYNTAX_ERRORPřeklep ve skriptu (chybějící uvozovka, nesprávný operátor)
TYPE_ERRORKombinujete typy, které spolu nefungují
RUNTIME_ERRORSkript se spustil, ale narazil na problém (nedefinovaná proměnná)
FETCH_LIMIT_EXCEEDEDNačítáte příliš mnoho dokumentů (maximum je 50)
TIMEOUTSkript trval příliš dlouho (maximum je 5 sekund)
AST_DEPTH_EXCEEDEDVýraz je příliš hluboce vnořený (maximální hloubka: 50)
SCRIPT_TOO_LONGSkript překračuje limit 5000 znaků

Rozšiřitelnost a budoucí možnosti

Modul CEL je navržen s ohledem na rozšiřitelnost. Mezi plánované budoucí možnosti patří:

Plánováno: Integrace serveru MCP

// Budoucí možnost: Volání externích služeb přes MCP
mcp.translate(meta.params.text, "en", meta.params.lang)
mcp.analyze(documents.get("article", meta.params.id).body)

Plánováno: Možnosti AI

// Budoucí možnost: Generování obsahu pomocí AI
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"])

Tyto možnosti budou přidávány prostřednictvím systému registrovaných funkcí při zachování zpětné kompatibility s existujícími skripty.


Tipy

  1. Používejte automatické doplňování – napište documents. nebo meta. a editor zobrazí dostupné možnosti
  2. Začněte jednoduše – nejprve otestujte documents.get("schema", "id") a teprve potom přidejte .fieldName
  3. Kontrolujte null – pokud dokument nemusí existovat, přidejte náhradní hodnotu pomocí != null ? ... : ...
  4. Načítejte jen potřebná data – každé documents.get() nebo documents.find() se započítává do limitu 50 načtení
  5. Upřednostňujte meta.params před meta.segments – pojmenované parametry jsou ověřené a spolehlivější
  6. Pro volitelné parametry používejte has() – před přístupem zkontrolujte has(meta.params.category)
  7. Pro dynamické identifikátory používejte documents.ref() – přehlednější syntaxe, když je schéma statické, ale identifikátor dynamický
  8. Pro odkazy na sebe sama používejte doc.fieldName – přístup k polím aktuálního dokumentu ve vypočítávaných výrazech

Odkazy mezi dokumenty

Tato část popisuje pokročilé vzory pro propojování dokumentů a vytváření relačních struktur obsahu.

Základní vzor odkazu

Nejjednodušší podoba: jeden dokument odkazuje na jiný pomocí identifikátoru.

// Článek ukládá ID autora, načte jméno autora
documents.get("author", documents.get("article", "intro").authorId).name

Řetězené vyhledávání pomocí documents.ref()

Pro přehlednější syntaxi, když je identifikátor dynamický:

// Tradiční přístup
documents.get("country", documents.get("airport", meta.params.code).countryCode).name

// Použití ref() – přehlednější, když je schéma známé, ale identifikátor dynamický
documents.ref("country").get(documents.get("airport", meta.params.code).countryCode).name

Víceúrovňové řetězení odkazů

Hluboké vztahy vytvoříte řetězením více vyhledávání:

// Letiště → Země → Region → Kontinent
documents.get("continent",
  documents.get("region",
    documents.get("country",
      documents.get("airport", meta.params.code).countryCode
    ).regionCode
  ).continentCode
).name

Odkaz s překladem

Kombinace odkazů mezi dokumenty a překladů:

// Získání lokalizovaného názvu země pro letiště
documents.translated("country",
  documents.get("airport", meta.params.code).countryCode,
  meta.params.lang
).name

Vzory odkazů podle případu použití

Vzor 1: Vyhledání pomocí cizího klíče

Dokument ukládá ID odkazující na jiný dokument.

// article / tech-news
{ "title": "Tech Update", "authorId": "author-123", "categoryId": "cat-tech" }
// Vyřešení jména autora
documents.get("author", documents.get("article", meta.params.slug).authorId).name

// Vyřešení kategorie s náhradní hodnotou
documents.get("article", meta.params.slug).categoryId != null
  ? documents.get("category", documents.get("article", meta.params.slug).categoryId).name
  : "Uncategorized"

Vzor 2: Odkazy založené na kódu

Dokumenty na sebe odkazují pomocí významových kódů namísto UUID.

// 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" }
// Řetězec Letiště → Země → Měna
documents.get("currency",
  documents.get("country",
    documents.get("airport", meta.params.code).countryCode
  ).currencyCode
).symbol
// Pro JFK: Vrátí "$"

Vzor 3: Odkazování na sebe pomocí kontextu doc

Použijte doc pro vypočítávaná pole, která odkazují na jiné dokumenty podle hodnot aktuálního dokumentu.

// V dokumentu produktu načte podrobnosti související kategorie
documents.get("category", doc.categoryId).description

// Vypočítávané přepravní náklady podle země původu produktu
documents.get("shipping-rates", doc.originCountry).baseRate * doc.weight

Vzor 4: Obousměrné odkazy

Pokud dokumenty odkazují jeden na druhý, dávejte pozor na limity načítání.

// Získá autora článku a poté další články autora (sledujte počet načtení!)
documents.find("article", { "where": { "authorId": documents.get("article", meta.params.slug).authorId } })

Vzor 5: Polymorfní odkazy

Když může pole odkazovat na různá schémata:

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

// content-block / hero-2
{ "type": "hero", "sourceType": "product", "sourceId": "featured-item" }
// Dynamické vyhledání schématu podle 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

Sledování závislostí

Každé volání documents.get(), documents.find() a documents.ref().get() se sleduje kvůli invalidaci mezipaměti. Když se odkazovaný dokument změní, CMS ví, které výrazy CEL je nutné znovu vyhodnotit.

Sledované závislosti zahrnují:

  • get: schema:identifier – závislost na konkrétním dokumentu
  • ref: schema:identifier – totéž co get prostřednictvím řetězené syntaxe
  • query: schema:* – závislost na úrovni schématu (libovolný dokument ve schématu)

Osvědčené postupy pro odkazy

  1. Minimalizujte hloubku řetězení – každá úroveň zvyšuje odezvu a počet načtení
  2. Ukládejte mezivýsledky do mezipaměti – pokud stejnou vnořenou hodnotu potřebujete dvakrát, načtěte rodiče jen jednou
  3. Používejte kontroly null – odkazy se mohou přerušit, pokud jsou dokumenty smazány
  4. Dávejte přednost kódům před UUID – kódy jsou ve výrazech čitelnější a stabilní napříč prostředími
  5. Sledujte limity načítání – složité řetězce odkazů mohou rychle narazit na limit 50 načtení
// Špatně: Stejný dokument načte dvakrát
documents.get("author", documents.get("article", "intro").authorId).name + " - " +
documents.get("author", documents.get("article", "intro").authorId).bio

// Lépe: Pomocí podmínky ověřte existenci jednou
documents.get("article", "intro").authorId != null
  ? documents.get("author", documents.get("article", "intro").authorId).name
  : "Unknown Author"

Dodatek A: Kompletní příklad parametrické routy

Tento návod vytvoří vícejazyčnou vstupní stránku dostupnou na /{lang}/landingPage.

Krok 1: Vytvoření schématu dokumentu pozdravu

V administraci CMS vytvořte vlastní schéma s názvem 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" }
  ]
}

Krok 2: Vytvoření dokumentů pozdravů

Vytvořte dokument pro každý jazyk:

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

Krok 3: Vytvoření stránky

Vytvořte stránku s následující konfigurací:

  • Cesta/vzor: /{lang}/landingPage
  • Stav: Živá
  • Mapování dynamických segmentů: namapujte lang na komponentu language
  {
    "lang": "language"
  }

Krok 4: Přidání bloků se skripty CEL

Přidejte do routy hero blok s těmito skripty CEL pro jednotlivá pole:

Pole nadpisu:

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

Pole podnadpisu:

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

Pole textu CTA:

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

Pole URL CTA:

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

Krok 5: Použití v Next.js

Přidejte catch-all routu. ParametricRoutePage vyřeší stránku, extrahuje meta.params z URL, vyhodnotí vaše vazby CEL na serveru a vykreslí každý blok prostřednictvím registru – kontext meta ani nízkoúrovňového klienta nemusíte vytvářet či volat sami.

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

Krok 6: Otestování rout

Navštivte tyto URL a zobrazte lokalizovaný obsah:

URLOčekávaný nadpis
/ko/landingPage환영
/en/landingPageWelcome
/ja/landingPageいらっしゃいませ

Jak funguje vyhodnocení

Když uživatel navštíví /ko/landingPage:

  1. Párování routy: CMS přiřadí vzor /{lang}/landingPage
  2. Extrakce parametru: meta.params.lang = "ko"
  3. Validace: CMS ověří, že &#32;„ko“ existuje ve schématu language
  4. Vyhodnocení CEL: Skripty jako documents.get("greeting", meta.params.lang) se vyhodnotí na korejský obsah
  5. Odpověď: Lokalizované bloky jsou vráceny klientovi

Dodatek B: Technická reference

Rozhraní CelMeta (TypeScript)

interface CelMeta {
  /** Kód aktuální lokalizace (např. 'en-US') */
  locale: string;
  /** Parametry routy extrahované z URL */
  params: Record<string, string>;
  /** Segmenty cesty URL */
  segments: string[];
  /** ID aktuálního dokumentu (při úpravě existujícího dokumentu) */
  docId: string | null;
  /** Název aktuálního dokumentu */
  title: string;
}

Algoritmus extrakce parametrů

Funkce extractParams zpracovává cesty URL:

Vzor:    /{country}/{lang}/products
Cesta:   /us/en/products

Algoritmus:
1. Normalizuj obě hodnoty (odstraň koncová lomítka)
2. Rozděl je na segmenty: ["us", "en", "products"] a ["{country}", "{lang}", "products"]
3. Porovnej počty segmentů (musí být stejné)
4. Pro každý pár segmentů:
   - Pokud vzor začíná na : nebo {}, extrahuj parametr
   - Jinak se musí přesně shodovat
5. Vrať: { country: "us", lang: "en" }

Podporované formáty vazeb parametrů

// Jednoduchá vazba (pro vyhledání používá pole "code")
{ "lang": "language" }

// Podrobná vazba (vlastní pole slug)
{
  "lang": {
    "schemaName": "language",
    "slugField": "code"
  },
  "slug": {
    "schemaName": "article",
    "slugField": "slug"
  }
}

Priorita vyhledávání dokumentů

Při načítání pomocí documents.get(schema, identifier):

  1. Shoda UUID: Pokud je identifikátor platné UUID, načte se podle id
  2. Pole code: Zkontroluje se pole content.code
  3. Pole slug: Zkontroluje se pole content.slug
  4. Shoda názvu: Zkontroluje se pole title

To umožňuje flexibilní odkazování na dokumenty pomocí libovolného jedinečného identifikátoru.

Continue Reading
Previous‹Nastavení proxy administračního paneluNextProject Scaffolding›