CMS์์ CEL ํํ์์ ์์ฑํ๊ธฐ ์ํ ์ค์ฉ ๊ฐ์ด๋์ ๋๋ค.
CMS์์ CEL ํํ์์ ์์ฑํ๊ธฐ ์ํ ์ค์ฉ ๊ฐ์ด๋์ ๋๋ค.
CEL(Common Expression Language)์ CMS์ ๋ด์ฅ๋ ๊ฐ๋ฒผ์ด ์คํฌ๋ฆฝํธ ์ธ์ด์ ๋๋ค. ๋ฌธ์์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ณ , URL ๋งค๊ฐ๋ณ์๋ฅผ ์ฝ๊ณ , ์ฆ์์์ ๊ฐ์ ๊ณ์ฐํ๋ ๋์ ํํ์์ ์์ฑํ ์ ์์ต๋๋ค.
CEL ์คํฌ๋ฆฝํธ๊ฐ ์คํ๋ ๋ ์ผ์ด๋๋ ๊ณผ์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
์ฌ์ฉ์ ์คํฌ๋ฆฝํธ ์์ง ๊ฒฐ๊ณผ
| | |
v v v
documents.get("article", "intro") --> ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ๊ฐ์ ธ์ต๋๋ค --> { headline: "Welcome", body: "..." }
.headline --> ํ๋๋ฅผ ์ถ์ถํฉ๋๋ค --> "Welcome"
CEL์ ์ฝ๊ธฐ ์ ์ฉ ์ฟผ๋ฆฌ ์ธ์ด๋ผ๊ณ ์๊ฐํ์ธ์. ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ด๋ค ๊ฒ๋ ์์ ํ ์ ์๊ณ , ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด์ ๊ณ์ฐ๋ ๊ฒฐ๊ณผ๋ง ๋ฐํํฉ๋๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ CMS ์ด๋์์๋ ์์ ํ๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๋ชจ๋ CEL ํํ์์ ์ธ ๊ฐ์ง ๊ฐ์ฒด์ ์ ๊ทผํ ์ ์์ต๋๋ค.
| ๊ฐ์ฒด | ์ค๋ช | ์์ |
|---|---|---|
documents | CMS์์ ์ด๋ค ๋ฌธ์๋ ๊ฐ์ ธ์ค๊ธฐ | documents.get("country", "us") |
meta | ํ์ฌ ์์ฒญ์ ๋ํ ์ ๋ณด(๋ก์ผ์ผ, URL ๋งค๊ฐ๋ณ์) | meta.locale, meta.params.slug |
schema | ํ์ฌ ๋ฌธ์์ ํ๋ ์ ์ | schema.fields |
doc๋ฅผ ์ฌ์ฉํ ์๊ธฐ ์ฐธ์กฐ๋ฌธ์ ํธ์ง๊ธฐ ์์์ CEL ํํ์์ ์์ฑํ ๋๋ doc ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํด ํ์ฌ ๋ฌธ์์ ํ๋ ๊ฐ์ ์ ๊ทผํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ๊ณ์ฐ ํ๋์ ํ๋ ๊ฐ ์ฐธ์กฐ๊ฐ ๊ฐ๋ฅํฉ๋๋ค.
// ํ์ฌ ๋ฌธ์์ price ํ๋์ ์ ๊ทผ
doc.price
// ํ์ฌ ๋ฌธ์ ํ๋๋ก ํฉ๊ณ ๊ณ์ฐ
doc.price * doc.quantity
// ํ์ฌ ๋ฌธ์ ์ํ์ ๋ฐ๋ฅธ ์กฐ๊ฑด ์ฒ๋ฆฌ
doc.status == "published" ? doc.title : "Draft: " + doc.title
doc ๊ฐ์ฒด์๋ ํธ์ง ์ค์ธ ๋ฌธ์์ ๋ชจ๋ ํ๋ ๊ฐ์ด ๋ค์ด ์์ต๋๋ค. ์ด๋ ๋ค์๊ณผ ๊ฐ์ ์ํฉ์์ ์ ์ฉํฉ๋๋ค.
doc.price * doc.quantity)CEL์ ๊ฐ์ฅ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ์ CMS ์ด๋์์๋ ๋ฌธ์๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋ค๋ ์ ์ ๋๋ค.
๊ตฌ๋ฌธ: documents.get(schemaName, identifier)
"welcome-post" ์๋ณ์๋ก ์ ์ฅ๋ article ๋ฌธ์๊ฐ ์๋ค๊ณ ๊ฐ์ ํด ๋ณด๊ฒ ์ต๋๋ค.
// CMS์ ์ ์ฅ๋ ํํ: article / welcome-post
{
"headline": "Welcome to Our Platform",
"author": "Sarah Chen",
"body": "We're excited to announce...",
"tags": ["announcement", "news"]
}
์ ์ฒด ๋ฌธ์๋ฅผ ๊ฐ์ ธ์ค๋ ค๋ฉด:
documents.get("article", "welcome-post")
๋ฐํ ๊ฒฐ๊ณผ:
{
"headline": "Welcome to Our Platform",
"author": "Sarah Chen",
"body": "We're excited to announce...",
"tags": ["announcement", "news"]
}
ํค๋๋ผ์ธ๋ง ๊ฐ์ ธ์ค๋ ค๋ฉด:
documents.get("article", "welcome-post").headline
๋ฐํ ๊ฒฐ๊ณผ: "Welcome to Our Platform"
์์ฑ์๋ฅผ ๊ฐ์ ธ์ค๋ ค๋ฉด:
documents.get("article", "welcome-post").author
๋ฐํ ๊ฒฐ๊ณผ: "Sarah Chen"
ํ์ด์ง์ /articles/[slug] ๊ฐ์ ๋์ ๋ผ์ฐํธ๊ฐ ์๋ค๋ฉด meta.params๋ฅผ ์ฌ์ฉํด URL ๋งค๊ฐ๋ณ์๋ฅผ ์ฝ๊ณ ์ฌ๋ฐ๋ฅธ ๋ฌธ์๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.
์ฌ์ฉ์๊ฐ /articles/welcome-post ์ ๋ฐฉ๋ฌธํ์ ๋:
documents.get("article", meta.params.slug).headline
๋ฐํ ๊ฒฐ๊ณผ: "Welcome to Our Platform"
์ด ๋ฐฉ์์ผ๋ก ๋์ ํ์ด์ง๋ฅผ ๊ตฌ์ฑํฉ๋๋ค. ๋์ผํ CEL ์คํฌ๋ฆฝํธ๊ฐ URL์ ์ด๋ค ์ฌ๋ฌ๊ทธ๊ฐ ์๋ ๋ชจ๋ ๊ธฐ์ฌ์์ ๋์ํฉ๋๋ค.
๊ตฌ๋ฌธ: documents.find(schemaName) ๋๋ documents.find(schemaName, filter)
// ๋ชจ๋ ๊ตญ๊ฐ ๊ฐ์ ธ์ค๊ธฐ
documents.find("country")
๋ฐํ ๊ฒฐ๊ณผ:
[
{ "code": "us", "name": "United States", "flag": "US" },
{ "code": "sa", "name": "Saudi Arabia", "flag": "SA" },
{ "code": "gb", "name": "United Kingdom", "flag": "GB" }
]
// ํํฐ๋ฅผ ์ฌ์ฉํด ๊ตญ๊ฐ ๊ฐ์ ธ์ค๊ธฐ
documents.find("country", { "where": { "code": "us" } })
๋ฐํ ๊ฒฐ๊ณผ:
[
{ "code": "us", "name": "United States", "flag": "US" }
]
CEL์ ์๋ ๋ก์ผ์ผ ๊ธฐ๋ฐ ๋ฒ์ญ๊ณผ ๋ช ์์ ๋ฒ์ญ ์กฐํ ๋ ๊ฐ์ง ๋ฐฉ์์ผ๋ก ๋ฒ์ญ๋ ๋ฌธ์ ์ฝํ ์ธ ๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.
meta.locale์ด ์ค์ ๋์ด ์์ผ๋ฉด(์: ๋ผ์ฐํธ ๋งค๊ฐ๋ณ์ ๋๋ ์ฌ์ฉ์ ์ ํธ) documents.get()์ด ์๋์ผ๋ก ๋ฒ์ญ๋ ์ฝํ
์ธ ๋ฅผ ๋ณํฉํฉ๋๋ค.
// meta.locale์ด "fr"์ด๋ฉด ๊ธฐ๋ณธ ๋ฌธ์์ ํ๋์ค์ด ๋ฒ์ญ์ ๋ณํฉํ์ฌ ๋ฐํ
documents.get("greeting", "welcome").headline
๋์ ๋ฐฉ์:
meta.locale์ด "en" ๋๋ "en-US"๊ฐ ์๋๋ฉด translations ํ
์ด๋ธ์์ ๋ฒ์ญ์ ์ฐพ์ต๋๋ค.{ ...baseContent, ...translatedContent }์ฆ, ๋ฒ์ญ๋ ํ๋๋ ๊ธฐ๋ณธ ํ๋๋ฅผ ๋ฎ์ด์ฐ๊ณ , ๋ฒ์ญ๋์ง ์์ ํ๋๋ ๊ธฐ๋ณธ ๋ฌธ์ ๊ฐ์ ๊ทธ๋๋ก ์ฌ์ฉํฉ๋๋ค.
ํ์ฌ ๋ก์ผ์ผ๊ณผ ๊ด๊ณ์์ด ํน์ ๋ฒ์ญ์ ๊ฐ์ ธ์์ผ ํ ๋ ์ฌ์ฉํฉ๋๋ค.
๊ตฌ๋ฌธ: documents.translated(schemaName, identifier, locale)
// ํญ์ ์คํ์ธ์ด ๋ฒ์ญ ๊ฐ์ ธ์ค๊ธฐ
documents.translated("greeting", "welcome", "es").headline
// URL ๋งค๊ฐ๋ณ์๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ฒ์ญ ๊ฐ์ ธ์ค๊ธฐ
documents.translated("product", meta.params.id, meta.params.lang).description
// ๋ฒ์ญ ๋น๊ตํ๊ธฐ
documents.translated("article", "intro", "en").title + " / " + documents.translated("article", "intro", "fr").title
๋ค์์ ๋ฒ์ญ์ด ํฌํจ๋ ์ธ์ฌ ๋ฌธ์์ ๋๋ค.
// ๊ธฐ๋ณธ ๋ฌธ์: greeting / welcome
{ "headline": "Welcome", "subheadline": "Welcome to our platform" }
// ๋ฒ์ญ(์ธ์ด: "fr")
{ "headline": "Bienvenue", "subheadline": "Bienvenue sur notre plateforme" }
// ๋ฒ์ญ(์ธ์ด: "es")
{ "headline": "Bienvenido", "subheadline": "Bienvenido a nuestra plataforma" }
CEL ์คํฌ๋ฆฝํธ:
// meta.locale = "fr"์ผ ๋
documents.get("greeting", "welcome").headline
// ๋ฐํ: "Bienvenue"
// ๋ช
์์ ์คํ์ธ์ด ๋ฒ์ญ
documents.translated("greeting", "welcome", "es").headline
// ๋ฐํ: "Bienvenido"
// ๋๋ฝ๋ ๋ฒ์ญ์ ๋ํ ํด๋ฐฑ ํจํด
documents.translated("greeting", "welcome", meta.params.lang) != null
? documents.translated("greeting", "welcome", meta.params.lang).headline
: documents.get("greeting", "welcome").headline
article ๋ฌธ์์์ ํค๋๋ผ์ธ์ ๊ฐ์ ธ์ ํ์ํด์ผ ํ๋ hero-block์ด ์๋ค๊ณ ๊ฐ์ ํฉ๋๋ค.
๊ธฐ์ฌ ๋ฌธ์(์๋ณ์: "homepage-hero"):
{
"headline": "Build Faster, Ship Smarter",
"subheadline": "The modern CMS for developers"
}
ํ์ด๋ก ๋ธ๋ก์ ์ ๋ชฉ ํ๋์ ์ฌ์ฉํ๋ CEL ์คํฌ๋ฆฝํธ:
documents.get("article", "homepage-hero").headline
๊ฒฐ๊ณผ: ํ์ด๋ก์๋ "Build Faster, Ship Smarter"๊ฐ ํ์๋ฉ๋๋ค.
/countries/[code] ํ์ด์ง์์ ์ ์ฒด ๊ตญ๊ฐ ์ด๋ฆ์ ํ์ํ๋ ค๊ณ ํฉ๋๋ค.
๊ตญ๊ฐ ๋ฌธ์:
// 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 ์คํฌ๋ฆฝํธ:
documents.get("country", meta.params.code).name
์ฌ์ฉ์๊ฐ /countries/us ๋ฅผ ๋ฐฉ๋ฌธํ๋ฉด:
meta.params.code = "us""United States"์ฌ์ฉ์๊ฐ /countries/sa ๋ฅผ ๋ฐฉ๋ฌธํ๋ฉด:
meta.params.code = "sa""Saudi Arabia"์ฌ์ฉ์ ๋ก์ผ์ผ์ ๋ฐ๋ผ ๋ค๋ฅธ ํค๋๋ผ์ธ์ ํ์ํฉ๋๋ค.
meta.locale == "ar-SA" ? "Welcome, everyone" : "Welcome"
๋ก์ผ์ผ์ด "ar-SA" ๋ผ๋ฉด: "Welcome, everyone" ๋ฐํ
๊ทธ ์ธ ๋ก์ผ์ผ์ด๋ผ๋ฉด: "Welcome" ๋ฐํ
article ๋ฌธ์์ countryCode ํ๋๊ฐ ์๊ณ , ๊ตญ๊ฐ์ ์ ์ฒด ์ด๋ฆ์ ๊ฐ์ ธ์ค๊ณ ์ถ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ํ ์ ์์ต๋๋ค.
๊ธฐ์ฌ ๋ฌธ์:
{ "headline": "News from the US", "countryCode": "us" }
CEL ์คํฌ๋ฆฝํธ:
documents.get("country", documents.get("article", "us-news").countryCode).name
์คํ ๊ณผ์ :
documents.get("article", "us-news")๋ { "headline": "News from the US", "countryCode": "us" }๋ฅผ ๋ฐํํฉ๋๋ค..countryCode๋ก "us"๋ฅผ ์ถ์ถํฉ๋๋ค.documents.get("country", "us")๋ { "code": "us", "name": "United States", ... }๋ฅผ ๋ฐํํฉ๋๋ค..name์ผ๋ก "United States"๋ฅผ ์ถ์ถํฉ๋๋ค.๊ฒฐ๊ณผ: "United States"
๋ฌธ์๊ฐ ์กด์ฌํ์ง ์์ ๊ฐ๋ฅ์ฑ์ด ์๋ค๋ฉด ํด๋ฐฑ์ ์ ๊ณตํ ์ ์์ต๋๋ค.
documents.get("article", meta.params.slug) != null
? documents.get("article", meta.params.slug).headline
: "Article Not Found"
๋๋ ํน์ ํ๋๊ฐ ์กด์ฌํ๋์ง ํ์ธํ ์ ์์ต๋๋ค.
documents.get("article", "intro").author != null
? documents.get("article", "intro").author
: "Unknown Author"
๊ธฐ์ฌ์ ํ๊ทธ๊ฐ ์๊ณ ํน์ ํ๊ทธ๊ฐ ์๋์ง ํ์ธํ๋ ค๋ฉด:
"featured" in documents.get("article", "welcome-post").tags
๋ฐํ ๊ฒฐ๊ณผ: ๊ธฐ์ฌ์ "featured" ํ๊ทธ๊ฐ ์์ผ๋ฉด true
์ฒซ ๋ฒ์งธ ํ๊ทธ ๊ฐ์ ธ์ค๊ธฐ:
documents.get("article", "welcome-post").tags[0]
๋ฐํ ๊ฒฐ๊ณผ: "announcement"(์ฒซ ๋ฒ์งธ ํ๊ทธ)
ํ๊ทธ ๊ฐ์ ์ธ๊ธฐ:
size(documents.get("article", "welcome-post").tags)
๋ฐํ ๊ฒฐ๊ณผ: 2(ํ๊ทธ ๊ฐ์)
ํ๋ผ๋ฉํธ๋ฆญ ๋ผ์ฐํธ๋ ๋์ ์ด๊ณ ํ์งํ๋ ํ์ด์ง๋ฅผ ๊ตฌ์ฑํ๋ ํต์ฌ์
๋๋ค. /{lang}/landingPage ๊ฐ์ ๋ผ์ฐํธ ํจํด์ ์ ์ํ๋ฉด CMS๊ฐ URL์์ ๋งค๊ฐ๋ณ์๋ฅผ ์ถ์ถํด meta.params๋ฅผ ํตํด ์ ๊ณตํฉ๋๋ค.
๋ผ์ฐํธ ํจํด ์ ์:
๋ผ์ฐํธ๋ ๋์ ๊ตฌ๊ฐ์ ์ ์ํ๊ธฐ ์ํด :paramName ๋๋ {paramName} ๊ตฌ๋ฌธ์ ์ฌ์ฉํฉ๋๋ค.
| ํจํด | ์์ URL | ์ถ์ถ๋ ๋งค๊ฐ๋ณ์ |
|---|---|---|
/:lang/landingPage | /ko/landingPage | { lang: "ko" } |
/{country}/{lang}/products | /us/en/products | { country: "us", lang: "en" } |
/articles/:slug | /articles/welcome-post | { slug: "welcome-post" } |
๋งค๊ฐ๋ณ์ ๋ฐ์ธ๋ฉ: ๊ฐ ๋ผ์ฐํธ ๋งค๊ฐ๋ณ์๋ ๊ฒ์ฆ์ ์ํด ๋ฌธ์ ์คํค๋ง์ ๋ฐ์ธ๋ฉํ ์ ์์ต๋๋ค.
{
"pattern": "/{lang}/landingPage",
"param_bindings": {
"lang": "language"
}
}
์ด ๋ฐ์ธ๋ฉ์ CMS์ ๋ค์์ ์ง์ํฉ๋๋ค.
lang ๊ตฌ๊ฐ์ ์ถ์ถํฉ๋๋ค.language ์คํค๋ง์ ๋ํด ๊ฒ์ฆํฉ๋๋ค(content.code๊ฐ ์ผ์นํ๋ ๋ฌธ์ ์ฐพ๊ธฐ).๋ผ์ฐํธ ๊ตฌ์ฑ:
/{lang}/landingPage/{lang}/landingPage{ "lang": "language" }์ธ์ฌ ๋ฌธ์:
// 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 ์คํฌ๋ฆฝํธ:
documents.get("greeting", meta.params.lang).headline
ํด์ ๋ฐฉ์:
| URL | meta.params.lang | ๊ฒฐ๊ณผ |
|---|---|---|
/ko/landingPage | "ko" | "Welcome" |
/en/landingPage | "en" | "Welcome" |
/ja/landingPage | "ja" | "Welcome" |
/{country}/{lang}/products ๊ฐ์ ๋ผ์ฐํธ๋ฅผ ์ํ ์์์
๋๋ค.
๋ผ์ฐํธ ๊ตฌ์ฑ:
{
"pattern": "/{country}/{lang}/products",
"param_bindings": {
"country": "country",
"lang": "language"
}
}
CEL ์คํฌ๋ฆฝํธ:
// ๊ตญ๊ฐ ์ด๋ฆ ๊ฐ์ ธ์ค๊ธฐ
documents.get("country", meta.params.country).name
// ๊ตญ๊ฐ์ ๋ฐ๋ผ ํ์งํ๋ ์ํ ๋ชฉ๋ก ๊ฐ์ ธ์ค๊ธฐ
documents.find("product", { "where": { "country": meta.params.country } })
// ๊ฒฐํฉ: ์ฌ์ฉ์์ ์ธ์ด๋ก ๊ตญ๊ฐ๋ณ ์ธ์ฌ๋ง ํ์
documents.get("greeting", meta.params.lang).headline + " from " + documents.get("country", meta.params.country).name
๊ฒ์ฆ ๊ณ์ธต ๊ตฌ์กฐ:
CMS๋ ๋งค๊ฐ๋ณ์๋ฅผ ๊ณ์ธต์ ์ผ๋ก ๊ฒ์ฆํฉ๋๋ค. /{country}/{lang} ๋ผ์ฐํธ์ ๊ฒฝ์ฐ:
country ๋งค๊ฐ๋ณ์๋ฅผ country ์คํค๋ง๋ก ๊ฒ์ฆํฉ๋๋ค.lang ๋งค๊ฐ๋ณ์๋ฅผ language ์คํค๋ง๋ก ๊ฒ์ฆํฉ๋๋ค.lang์ด country.languages[] ๋ฐฐ์ด์ ์๋์ง๊น์ง ํ์ธํฉ๋๋ค(๊ณ์ธต์ ๊ฒ์ฆ).meta.segments๋ URL ๊ฒฝ๋ก๋ฅผ ๋ฐฐ์ด ํํ๋ก ์ ๊ณตํ์ฌ ์ด๋ฆ ์๋ ๋งค๊ฐ๋ณ์๊ฐ ์๋ ๊ฒฝ์ฐ ์์น ๊ธฐ๋ฐ ์ ๊ทผ์ ์ ์ฉํฉ๋๋ค.
๋์ ๋ฐฉ์:
| URL ๊ฒฝ๋ก | meta.segments |
|---|---|
/articles/tech/ai-news | ["articles", "tech", "ai-news"] |
/ko/landingPage | ["ko", "landingPage"] |
/us/en/products/featured | ["us", "en", "products", "featured"] |
/ | [] |
| ์ฌ์ฉ ์ฌ๋ก | ์ต์ ์ ์ ๊ทผ ๋ฐฉ์ |
|---|---|
| ๋ผ์ฐํธ ํจํด์์ ์ถ์ถํ ์ด๋ฆ ์๋ ๋งค๊ฐ๋ณ์ | meta.params.lang |
| ์์น ๊ธฐ๋ฐ ์ ๊ทผ | meta.segments[0] |
| ๊ฒฝ๋ก ๊น์ด ํ์ธ | size(meta.segments) |
| ํน์ ๊ตฌ๊ฐ ์กด์ฌ ์ฌ๋ถ ํ์ธ | "admin" in meta.segments |
// ์ฒซ ๋ฒ์งธ ๊ตฌ๊ฐ ๊ฐ์ ธ์ค๊ธฐ(์ฃผ๋ก ์ธ์ด ์ฝ๋)
meta.segments[0]
// ๊ฒฝ๋ก ๊น์ด ํ์ธ
size(meta.segments) > 2 ? "deep" : "shallow"
// ๊ด๋ฆฌ์ ์์ญ์ธ์ง ํ์ธ
"admin" in meta.segments ? "admin mode" : "public mode"
// ํด๋ฐฑ: ๋งค๊ฐ๋ณ์๊ฐ ๋ฐ์ธ๋ฉ๋์ง ์์๋ค๋ฉด ๊ตฌ๊ฐ ์ฌ์ฉ
has(meta.params.lang) ? meta.params.lang : meta.segments[0]
meta ๊ฐ์ฒด์๋ ํ์ฌ ์์ฒญ์ ๋ํ ๋ชจ๋ ์ปจํ
์คํธ๊ฐ ๋ด๊ฒจ ์์ต๋๋ค.
| ์์ฑ | ํ์ | ์ค๋ช | |
|---|---|---|---|
meta.locale | string | ํ์ฌ ๋ก์ผ์ผ ์ฝ๋(์: "en-US", "ko-KR", "ar-SA") | |
meta.params | Record<string, string> | URL ํจํด์์ ์ถ์ถํ ๋ผ์ฐํธ ๋งค๊ฐ๋ณ์ | |
meta.segments | string[] | URL ๊ฒฝ๋ก๋ฅผ ๋ถํ ํ ๋ฐฐ์ด | |
meta.docId | `string \ | null` | ํ์ฌ ๋ฌธ์ UUID(์ ๋ฌธ์์ผ ๋๋ null) |
meta.title | string | ํ์ฌ ๋ฌธ์ ์ ๋ชฉ |
๋ก์ผ์ผ ์ฝ๋๋ BCP 47 ํ์(์ธ์ด-์ง์ญ)์ ๋ฐ๋ฆ ๋๋ค.
// ๋ก์ผ์ผ์ ํ์ธํด RTL ์ธ์ด์ธ์ง ํ์
meta.locale == "ar-SA" || meta.locale == "he-IL" ? "rtl" : "ltr"
// ์ธ์ด ๋ถ๋ถ๋ง ๊ฐ์ ธ์ค๊ธฐ
meta.locale.split("-")[0] // ์ง์๋์ง ์์ - ๋์ meta.params.lang ์ฌ์ฉ
๋ผ์ฐํธ ๋งค๊ฐ๋ณ์๋ ํญ์ ๋ฌธ์์ด์ ๋๋ค. CMS๋ ํ๊ฐ ์ ์ ๋ฐ์ธ๋ฉ๋ ์คํค๋ง๋ก ์ด๋ฅผ ๊ฒ์ฆํฉ๋๋ค.
// ์ด๋ฆ ์๋ ๋งค๊ฐ๋ณ์์ ์ ๊ทผ
meta.params.lang // "ko"
meta.params.country // "us"
meta.params.slug // "welcome-post"
// ๋งค๊ฐ๋ณ์๊ฐ ์กด์ฌํ๋์ง ํ์ธ
has(meta.params.category) // true/false
// ๋ฌธ์ ์กฐํ์ ์ฌ์ฉ
documents.get("greeting", meta.params.lang)
documents.ref("airports").get(meta.params.code)
์์ URL ๊ตฌ๊ฐ์ ๋ฐฐ์ด๋ก ์ ๊ณต๋ฉ๋๋ค.
// ์ธ๋ฑ์ค๋ก ์ ๊ทผ(0๋ถํฐ ์์)
meta.segments[0] // ์ฒซ ๋ฒ์งธ ๊ตฌ๊ฐ
meta.segments[1] // ๋ ๋ฒ์งธ ๊ตฌ๊ฐ
// ๊ธธ์ด ํ์ธ
size(meta.segments) // ๊ตฌ๊ฐ ์
// ํฌํจ ์ฌ๋ถ ํ์ธ
"products" in meta.segments // ๊ฒฝ๋ก์ "products"๊ฐ ํฌํจ๋์ด ์๋๊ฐ?
ํ์ฌ ๋ฌธ์์ UUID๋ก, ์๊ธฐ ์ฐธ์กฐ ์คํฌ๋ฆฝํธ์ ์ ์ฉํฉ๋๋ค.
// ๊ธฐ์กด ๋ฌธ์๋ฅผ ํธ์ง ์ค์ผ ๋๋ง ์ฌ์ฉ ๊ฐ๋ฅ
meta.docId != null ? "editing" : "creating new"
// ์กฐ๊ฑด๋ถ ๋ก์ง์ ์ฌ์ฉ
meta.docId != null ? documents.get("article", meta.docId).status : "draft"
ํ์ฌ ๋ฌธ์์ ์ ๋ชฉ์ ๋๋ค.
// ํ์์ฉ
"Editing: " + meta.title
// ์ ๋ชฉ ๊ธฐ๋ฐ ์กฐ๊ฑด๋ถ ์ฒ๋ฆฌ
meta.title.contains("Draft") ? "work in progress" : "published"
์คํค๋ง๋ ๊ณ ์ ๋์ด ์๊ณ ์๋ณ์๋ง ๋์ ์ธ ๊ฒฝ์ฐ ๋ ๊น๋ํ ๊ตฌ๋ฌธ์ ์ ๊ณตํฉ๋๋ค.
// ์ ํต์ ์ธ ์ ๊ทผ ๋ฐฉ์
documents.get("airports", meta.params.code).name
// ref() ์ฌ์ฉ - ์คํค๋ง๋ ๋ถ๋ฆฌํ๊ณ ์๋ณ์๋ง ๋์ ์ผ๋ก
documents.ref("airports").get(meta.params.code).name
๋ ๋ฐฉ์ ๋ชจ๋ ๋์ผํ์ง๋ง, ref()๋ ๋์ ์ธ ๋ถ๋ถ์ ๋ ๋ช
ํํ๊ฒ ๋ณด์ฌ ์ค๋๋ค.
documents.get("schema", "identifier") // ๋ฌธ์ ํ๋ ๊ฐ์ ธ์ค๊ธฐ
documents.get("schema", "id").fieldName // ํน์ ํ๋ ๊ฐ์ ธ์ค๊ธฐ
documents.find("schema") // ๋ชจ๋ ๋ฌธ์ ๊ฐ์ ธ์ค๊ธฐ
documents.find("schema", { "where": {...}}) // ํํฐ ์ฟผ๋ฆฌ
documents.ref("schema").get(identifier) // ์ฒด์ด๋ ์กฐํ
documents.translated("schema", "id", "fr") // ๋ช
์์ ๋ก์ผ์ผ๋ก ๊ฐ์ ธ์ค๊ธฐ
meta.locale // "en-US", "ar-SA" ๋ฑ
meta.params.xyz // "xyz"๋ผ๋ ์ด๋ฆ์ URL ๋งค๊ฐ๋ณ์
meta.segments // URL ๊ฒฝ๋ก ๋ฐฐ์ด: ["articles", "intro"]
meta.segments[0] // ์ฒซ ๋ฒ์งธ ๊ฒฝ๋ก ๊ตฌ๊ฐ
meta.docId // ํ์ฌ ๋ฌธ์ ID(๋๋ null)
meta.title // ํ์ฌ ๋ฌธ์ ์ ๋ชฉ
doc.fieldName // ํธ์ง๊ธฐ ์ปจํ
์คํธ์์ ํ์ฌ ๋ฌธ์ ํ๋ ๊ฐ
// ๋น๊ต
== != < <= > >=
// ๋
ผ๋ฆฌ
&& || !
// ์ผํญ ์ฐ์ฐ์(์กฐ๊ฑด๋ถ)
condition ? valueIfTrue : valueIfFalse
// ๋ฉค๋ฒ์ญ
"value" in listOrMap
size(list) // ํญ๋ชฉ ์
size(string) // ๋ฌธ์์ด ๊ธธ์ด
"text".startsWith("te") // true
"text".endsWith("xt") // true
"text".contains("ex") // true
has(object.property) // ์์ฑ ์กด์ฌ ์ฌ๋ถ ํ์ธ
hasProperty(obj, "key") // ๊ฐ์ฒด์ ํค๊ฐ ์๋์ง ํ์ธ(๋์ฒด ๊ตฌ๋ฌธ)
๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ฉด ๋ค์ ์ค ํ๋์ ์ค๋ฅ๋ฅผ ๋ณผ ์ ์์ต๋๋ค.
| ์ค๋ฅ | ์๋ฏธ |
|---|---|
SYNTAX_ERROR | ์คํฌ๋ฆฝํธ์ ์คํ๊ฐ ์์(๋ฐ์ดํ ๋๋ฝ, ์๋ชป๋ ์ฐ์ฐ์ ๋ฑ) |
TYPE_ERROR | ํธํ๋์ง ์๋ ํ์ ์ ํผํฉํจ |
RUNTIME_ERROR | ์คํฌ๋ฆฝํธ๋ ์คํ๋์์ง๋ง ๋ฌธ์ ๋ฐ์(์ ์๋์ง ์์ ๋ณ์ ๋ฑ) |
FETCH_LIMIT_EXCEEDED | ๋๋ฌด ๋ง์ ๋ฌธ์๋ฅผ ๊ฐ์ ธ์ด(์ต๋ 50๊ฐ) |
TIMEOUT | ์คํฌ๋ฆฝํธ ์คํ ์๊ฐ์ด ๋๋ฌด ๊น(์ต๋ 5์ด) |
AST_DEPTH_EXCEEDED | ํํ์์ด ๋๋ฌด ๊น๊ฒ ์ค์ฒฉ๋จ(์ต๋ ๊น์ด: 50) |
SCRIPT_TOO_LONG | ์คํฌ๋ฆฝํธ ๊ธ์ ์๊ฐ 5000์๋ฅผ ์ด๊ณผํจ |
CEL ์์ง์ ํ์ฅ์ฑ์ ์ผ๋์ ๋๊ณ ์ค๊ณ๋์์ต๋๋ค. ๋ค์์ ์์ ๋ ๊ธฐ๋ฅ์ ๋๋ค.
// ํฅํ: MCP๋ฅผ ํตํด ์ธ๋ถ ์๋น์ค ํธ์ถ
mcp.translate(meta.params.text, "en", meta.params.lang)
mcp.analyze(documents.get("article", meta.params.id).body)
// ํฅํ: 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"])
์ด๋ฌํ ๊ธฐ๋ฅ์ ๋ฑ๋ก๋ ํจ์ ์์คํ ์ ํตํด ์ถ๊ฐ๋๋ฉฐ, ๊ธฐ์กด ์คํฌ๋ฆฝํธ์์ ํ์ ํธํ์ฑ์ ์ ์งํฉ๋๋ค.
documents. ๋๋ meta.๋ฅผ ์
๋ ฅํ๋ฉด ํธ์ง๊ธฐ๊ฐ ์ฌ์ฉ ๊ฐ๋ฅํ ์ต์
์ ๋ณด์ฌ ์ค๋๋ค.documents.get("schema", "id")๋ก ํ
์คํธํ ํ .fieldName์ ์ถ๊ฐํ์ธ์.!= null ? ... : ...์ผ๋ก ํด๋ฐฑ์ ์ถ๊ฐํ์ธ์.documents.get() ๋๋ documents.find() ํธ์ถ์ 50ํ ์ ํ์ ํฌํจ๋ฉ๋๋ค.has(meta.params.category)๋ฅผ ํ์ธํ์ธ์.์ด ์น์ ์์๋ ๋ฌธ์ ๊ฐ ์ฐ๊ฒฐ๊ณผ ๊ด๊ณํ ์ฝํ ์ธ ๊ตฌ์กฐ๋ฅผ ๊ตฌ์ถํ๋ ๊ณ ๊ธ ํจํด์ ๋ค๋ฃน๋๋ค.
๊ฐ์ฅ ๋จ์ํ ํํ๋ ํ ๋ฌธ์๊ฐ ๋ค๋ฅธ ๋ฌธ์๋ฅผ ์๋ณ์๋ก ์ฐธ์กฐํ๋ ๊ฒ์ ๋๋ค.
// ๊ธฐ์ฌ์ ์ ์ฅ๋ author ID๋ก ์์ฑ์ ์ด๋ฆ ๊ฐ์ ธ์ค๊ธฐ
documents.get("author", documents.get("article", "intro").authorId).name
์๋ณ์๊ฐ ๋์ ์ผ ๋ ๋ ๊น๋ํ ๊ตฌ๋ฌธ์ ์ ๊ณตํฉ๋๋ค.
// ์ ํต์ ์ ๊ทผ
documents.get("country", documents.get("airport", meta.params.code).countryCode).name
// ref() ์ฌ์ฉ - ์คํค๋ง๋ ๊ณ ์ , ์๋ณ์๋ ๋์
documents.ref("country").get(documents.get("airport", meta.params.code).countryCode).name
์ฌ๋ฌ ๋จ๊ณ๋ก ์ฒด์ธ์ ๊ตฌ์ฑํด ๊น์ ๊ด๊ณ๋ฅผ ๊ตฌ์ถํฉ๋๋ค.
// ๊ณตํญ โ ๊ตญ๊ฐ โ ์ง์ญ โ ๋๋ฅ
documents.get("continent",
documents.get("region",
documents.get("country",
documents.get("airport", meta.params.code).countryCode
).regionCode
).continentCode
).name
๋ฌธ์ ์ฐธ์กฐ๋ฅผ ๋ฒ์ญ๊ณผ ๊ฒฐํฉํ ์ ์์ต๋๋ค.
// ๊ณตํญ์ ๊ตญ๊ฐ ์ด๋ฆ์ ํ์งํํด์ ๊ฐ์ ธ์ค๊ธฐ
documents.translated("country",
documents.get("airport", meta.params.code).countryCode,
meta.params.lang
).name
๋ฌธ์์ ๋ค๋ฅธ ๋ฌธ์์ ID๋ฅผ ์ ์ฅํฉ๋๋ค.
// article / tech-news
{ "title": "Tech Update", "authorId": "author-123", "categoryId": "cat-tech" }
// ์์ฑ์ ์ด๋ฆ ํ์ธ
documents.get("author", documents.get("article", meta.params.slug).authorId).name
// ์นดํ
๊ณ ๋ฆฌ๋ฅผ ํด๋ฐฑ๊ณผ ํจ๊ป ํ์ธ
documents.get("article", meta.params.slug).categoryId != null
? documents.get("category", documents.get("article", meta.params.slug).categoryId).name
: "Uncategorized"
๋ฌธ์๊ฐ 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" }
// ๊ณตํญ โ ๊ตญ๊ฐ โ ํตํ ์ฒด์ธ
documents.get("currency",
documents.get("country",
documents.get("airport", meta.params.code).countryCode
).currencyCode
).symbol
// JFK์ ๊ฒฝ์ฐ: "$" ๋ฐํ
ํ์ฌ ๋ฌธ์์ ๊ฐ์ ๊ธฐ๋ฐ์ผ๋ก ๋ค๋ฅธ ๋ฌธ์๋ฅผ ์ฐธ์กฐํ๋ ๊ณ์ฐ ํ๋์ doc์ ์ฌ์ฉํฉ๋๋ค.
// ์ํ ๋ฌธ์์์ ๊ด๋ จ ์นดํ
๊ณ ๋ฆฌ ์ธ๋ถ ์ ๋ณด ๊ฐ์ ธ์ค๊ธฐ
documents.get("category", doc.categoryId).description
// ์ํ์ ์์ฐ์ง ๊ตญ๊ฐ์ ๋ฐ๋ผ ๋ฐฐ์ก๋น ๊ณ์ฐ
documents.get("shipping-rates", doc.originCountry).baseRate * doc.weight
๋ฌธ์๊ฐ ์๋ก๋ฅผ ์ฐธ์กฐํ ๋๋ ์กฐํ ์ ํ์ ์ฃผ์ํ์ธ์.
// ๊ธฐ์ฌ ์์ฑ์๋ฅผ ๊ฐ์ ธ์จ ๋ค์, ๊ทธ ์์ฑ์์ ๋ค๋ฅธ ๊ธฐ์ฌ ๊ฐ์ ธ์ค๊ธฐ(์กฐํ ํ์ ์ฃผ์)
documents.find("article", { "where": { "authorId": documents.get("article", meta.params.slug).authorId } })
ํ๋์ ํ๋๊ฐ ์๋ก ๋ค๋ฅธ ์คํค๋ง๋ฅผ ์ฐธ์กฐํ ์ ์์ ๋ ์ฌ์ฉํฉ๋๋ค.
// content-block / hero-1
{ "type": "hero", "sourceType": "article", "sourceId": "welcome-post" }
// content-block / hero-2
{ "type": "hero", "sourceType": "product", "sourceId": "featured-item" }
// 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
๋ชจ๋ documents.get(), documents.find(), documents.ref().get() ํธ์ถ์ ์บ์ ๋ฌดํจํ๋ฅผ ์ํด ์ถ์ ๋ฉ๋๋ค. ์ฐธ์กฐ๋ ๋ฌธ์๊ฐ ๋ณ๊ฒฝ๋๋ฉด CMS๋ ์ด๋ค CEL ํํ์์ ๋ค์ ํ๊ฐํด์ผ ํ ์ง ์๊ณ ์์ต๋๋ค.
์ถ์ ๋๋ ์์กด์ฑ:
schema:identifier - ํน์ ๋ฌธ์ ์์กด์ฑschema:identifier - ์ฒด์ด๋ ๊ตฌ๋ฌธ์ ํตํ get๊ณผ ๋์ผschema:* - ์คํค๋ง ์์ค ์์กด์ฑ(ํด๋น ์คํค๋ง์ ๋ชจ๋ ๋ฌธ์)// ๋์ ์: ๋์ผํ ๋ฌธ์๋ฅผ ๋ ๋ฒ ์กฐํ
documents.get("author", documents.get("article", "intro").authorId).name + " - " +
documents.get("author", documents.get("article", "intro").authorId).bio
// ๋ ๋์ ์: ํ ๋ฒ๋ง ์กฐ๊ฑด ํ์ธ
documents.get("article", "intro").authorId != null
? documents.get("author", documents.get("article", "intro").authorId).name
: "Unknown Author"
์ด ์ํฌ์ค๋ฃจ์์๋ /{lang}/landingPage๋ก ์ ๊ทผ ๊ฐ๋ฅํ ๋ค๊ตญ์ด ๋๋ฉ ํ์ด์ง๋ฅผ ๋ง๋ญ๋๋ค.
CMS ๊ด๋ฆฌ์์์ 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" }
]
}
์ธ์ด๋ณ๋ก ๋ฌธ์๋ฅผ ์์ฑํฉ๋๋ค.
๋ฌธ์: 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"
}
๋ค์ ๊ตฌ์ฑ์ผ๋ก ํ์ด์ง๋ฅผ ์์ฑํฉ๋๋ค.
/{lang}/landingPagelang์ language ์ปดํฌ๋ํธ์ ๋งคํ {
"lang": "language"
}
๋ผ์ฐํธ์ ํ์ด๋ก ๋ธ๋ก์ ์ถ๊ฐํ๊ณ ๊ฐ ํ๋์ ๋ค์ CEL ์คํฌ๋ฆฝํธ๋ฅผ ์ค์ ํฉ๋๋ค.
ํค๋๋ผ์ธ ํ๋:
documents.get("greeting", meta.params.lang).headline
์๋ธํค๋๋ผ์ธ ํ๋:
documents.get("greeting", meta.params.lang).subheadline
CTA ํ ์คํธ ํ๋:
documents.get("greeting", meta.params.lang).ctaText
CTA URL ํ๋:
documents.get("greeting", meta.params.lang).ctaUrl
์บ์น์ฌ ๋ผ์ฐํธ๋ฅผ ์ถ๊ฐํฉ๋๋ค. ParametricRoutePage๋ ํ์ด์ง๋ฅผ ํด์ํ๊ณ URL์์ meta.params๋ฅผ ์ถ์ถํ๋ฉฐ, ์๋ฒ ์ธก์์ CEL ๋ฐ์ธ๋ฉ์ ํ๊ฐํ ๋ค ๊ฐ ๋ธ๋ก์ ๋ ์ง์คํธ๋ฆฌ๋ฅผ ํตํด ๋ ๋๋งํฉ๋๋ค. meta ์ปจํ
์คํธ๋ฅผ ์ง์ ๊ตฌ์ฑํ๊ฑฐ๋ ๋ก์ฐ ๋ ๋ฒจ ํด๋ผ์ด์ธํธ๋ฅผ ํธ์ถํ ํ์๊ฐ ์์ต๋๋ค.
// 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 })}
/>
);
}
๋ค์ URL์ ๋ฐฉ๋ฌธํด ํ์งํ๋ ์ฝํ ์ธ ๋ฅผ ํ์ธํ์ธ์.
| URL | ์์ ํค๋๋ผ์ธ |
|---|---|
/ko/landingPage | ํ์ |
/en/landingPage | Welcome |
/ja/landingPage | ใใใฃใใใใพใ |
์ฌ์ฉ์๊ฐ /ko/landingPage๋ฅผ ๋ฐฉ๋ฌธํ๋ฉด:
/{lang}/landingPage ํจํด์ ๋งค์นญํฉ๋๋ค.meta.params.lang = "ko"language ์คํค๋ง์์ "ko"๊ฐ ์กด์ฌํ๋์ง ๊ฒ์ฆํฉ๋๋ค.documents.get("greeting", meta.params.lang) ๊ฐ์ ์คํฌ๋ฆฝํธ๊ฐ ํ๊ตญ์ด ์ฝํ
์ธ ๋ก ํ๊ฐ๋ฉ๋๋ค.interface CelMeta {
/** Current locale code (e.g., 'en-US') */
locale: string;
/** Route parameters extracted from URL */
params: Record<string, string>;
/** URL path segments */
segments: string[];
/** Current document ID (if editing existing document) */
docId: string | null;
/** Current document title */
title: string;
}
extractParams ํจ์๋ URL ๊ฒฝ๋ก๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์ฒ๋ฆฌํฉ๋๋ค.
ํจํด: /{country}/{lang}/products
๊ฒฝ๋ก: /us/en/products
์๊ณ ๋ฆฌ์ฆ:
1. ๋ ๋ค ์ ๊ทํ(ํํ ์ฌ๋์ ์ ๊ฑฐ)
2. ๊ตฌ๊ฐ์ผ๋ก ๋ถํ : ["us", "en", "products"]์ ["{country}", "{lang}", "products"]
3. ๊ตฌ๊ฐ ๊ฐ์๊ฐ ์ผ์นํด์ผ ํจ
4. ๊ฐ ๊ตฌ๊ฐ ์์ ๋ํด:
- ํจํด์ด : ๋๋ {}๋ก ์์ํ๋ฉด ๋งค๊ฐ๋ณ์๋ก ์ถ์ถ
- ๊ทธ๋ ์ง ์์ผ๋ฉด ์ ํํ ์ผ์นํด์ผ ํจ
5. ๋ฐํ: { country: "us", lang: "en" }
// ๊ฐ๋จํ ๋ฐ์ธ๋ฉ("code" ํ๋๋ก ์กฐํ)
{ "lang": "language" }
// ์ธ๋ถ ๋ฐ์ธ๋ฉ(๋ง์ถค ์ฌ๋ฌ๊ทธ ํ๋)
{
"lang": {
"schemaName": "language",
"slugField": "code"
},
"slug": {
"schemaName": "article",
"slugField": "slug"
}
}
documents.get(schema, identifier)๋ก ๊ฐ์ ธ์ฌ ๋์ ์ฐ์ ์์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
id๋ก ๊ฐ์ ธ์ต๋๋ค.content.code ํ๋๋ฅผ ํ์ธํฉ๋๋ค.content.slug ํ๋๋ฅผ ํ์ธํฉ๋๋ค.title ํ๋๋ฅผ ํ์ธํฉ๋๋ค.์ด๋ ๊ฒ ํ๋ฉด ์ด๋ค ๊ณ ์ ์๋ณ์๋ฅผ ์ฌ์ฉํ๋ ์ ์ฐํ๊ฒ ๋ฌธ์๋ฅผ ์ฐธ์กฐํ ์ ์์ต๋๋ค.