All Systems Operational
Powered By
profound-logo
profound-logoProfound CMS
⌘K
Admin

Şablon Oluşturucuda Betik Yazma

CMS'de CEL ifadeleri yazmaya yönelik pratik bir rehber.

Continue Reading
Previous‹Duzenleme Modu Destegiyle Statik IslemeNextCreate Profound Next›

Hibrit

Renderer ProjesiParametrik YönlendirmeBileşenler TürleriSseYönetici paneli proxy kurulumuDuzenleme Modu Destegiyle Statik IslemeŞablon Oluşturucuda Betik YazmaCreate Profound Next

Başsız

Hızlı başlangıçJson Ve Claude KodBileşen Zod Çekme

Mcp

Mcp

Cms Özellikleri

Özellik Belgeler ŞablonuÖzellik Şablon OluşturucuÖzellik ÇeviriciÖzellik Organizasyon

Motivasyon

Bizim yaklaşımımız

Terminoloji

Hibrit Vs Headless

CMS'de CEL ifadeleri yazmaya yönelik pratik bir rehber.


CEL Nasıl Çalışır

CEL (Common Expression Language), CMS'imize yerleşik hafif bir betik dilidir. Belgelerden veri çekmenize, URL parametrelerini okumanıza ve değerleri anında hesaplamanıza olanak tanıyan dinamik ifadeler yazmanızı sağlar.

Bir CEL betiği çalıştığında neler olur:

Betiğiniz                      Motor                          Sonuç
    |                              |                              |
    v                              v                              v
documents.get("article", "intro") --> Veritabanından alır --> { headline: "Welcome", body: "..." }
         .headline                --> Alanı çıkarır         --> "Welcome"

CEL'i salt okunur bir sorgu dili gibi düşünebilirsiniz. Veritabanındaki hiçbir şeyi değiştiremez; sadece verileri okur ve hesaplanmış bir sonuç döndürür. Bu da onu CMS'nin her yerinde güvenle kullanabileceğiniz anlamına gelir.


Temel Bileşenler

Her CEL ifadesinin erişebildiği üç şey vardır:

NesneNedirÖrnek
documentsCMS'den herhangi bir belgeyi getirirdocuments.get("country", "us")
metaGeçerli isteğe dair bilgiler (yerel ayar, URL parametreleri)meta.locale, meta.params.slug
schemaGeçerli belgenin alan tanımlarıschema.fields

Belgeleri Getirme

CEL'in en güçlü özelliği, CMS'nizdeki herhangi bir yerden belgeleri çekebilmesidir.

Tek Bir Belgeyi Getirme

Sözdizimi: documents.get(schemaName, identifier)

Tanımlayıcısı "welcome-post" olan bir article belgeniz olduğunu varsayalım:

// CMS'de şu şekilde saklanır: article / welcome-post
{
  "headline": "Welcome to Our Platform",
  "author": "Sarah Chen",
  "body": "We're excited to announce...",
  "tags": ["announcement", "news"]
}

Belgenin tamamını getirmek için:

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

Döndürür:

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

Yalnızca başlığı getirmek için:

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

Döndürür: "Welcome to Our Platform"

Yazarı getirmek için:

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

Döndürür: "Sarah Chen"


URL Parametrelerini Kullanma

Sayfanız dinamik rotalara sahipse (örneğin /articles/[slug]), meta.params ile URL parametresini alıp doğru belgeyi getirebilirsiniz.

Birisi /articles/welcome-post adresini ziyaret ederse:

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

Döndürür: "Welcome to Our Platform"

Bu şekilde dinamik sayfalar oluşturursunuz — aynı CEL betiği, URL'deki slug ne olursa olsun her makale için çalışır.


Birden Fazla Belgeyi Getirme

Sözdizimi: documents.find(schemaName) veya documents.find(schemaName, filter)

// Tüm ülkeleri getir
documents.find("country")

Döndürür:

[
  { "code": "us", "name": "United States", "flag": "US" },
  { "code": "sa", "name": "Saudi Arabia", "flag": "SA" },
  { "code": "gb", "name": "United Kingdom", "flag": "GB" }

// Filtre ile ülkeleri getir
documents.find("country", { "where": { "code": "us" } })

Döndürür:

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

Gerçek Dünya Örnekleri

Örnek 1: Başka Bir Belgeden Hero Blok Başlığı

hero-block bileşeninizin, bir article belgesinden alınan başlığı göstermesi gerekiyor.

Makale belgeniz (tanımlayıcı: "homepage-hero"):

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

Hero bloğunun başlık alanındaki CEL betiği:

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

Sonuç: Hero, "Build Faster, Ship Smarter" metnini gösterir.


Örnek 2: Koddan Ülke Adı

/countries/[code] adresinde bir sayfa oluşturuyor ve tam ülke adını göstermek istiyorsunuz.

Ülke belgeleriniz:

// 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 betiği:

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

Birisi /countries/us adresini ziyaret ettiğinde:

  • meta.params.code = "us"
  • Sonuç: "United States"

Birisi /countries/sa adresini ziyaret ettiğinde:

  • meta.params.code = "sa"
  • Sonuç: "Saudi Arabia"

Örnek 3: Yerel Ayara Göre Koşullu İçerik

Kullanıcının yerel ayarına göre farklı başlıklar gösterin.

meta.locale == "ar-SA" ? "مرحبا بكم" : "Welcome"

Yerel ayar "ar-SA" ise: "مرحبا بكم" döner. Yerel ayar başka bir şeyse: "Welcome" döner.


Örnek 4: Zincirleme Belge Aramaları

article belgenizde bir countryCode alanı var ve tam ülke adını almak istiyorsunuz.

Makale belgesi:

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

CEL betiği:

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

Ne olur:

  1. documents.get("article", "us-news") değeri { "headline": "News from the US", "countryCode": "us" } döndürür.
  2. .countryCode "us" değerini çeker.
  3. documents.get("country", "us") değeri { "code": "us", "name": "United States", ... } döndürür.
  4. .name "United States" değerini alır.

Sonuç: "United States"


Örnek 5: Yedek Değerler

Bir belgenin olmayabileceği durumlarda yedek değer sağlayabilirsiniz:

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

Ya da belirli bir alanın var olup olmadığını kontrol edin:

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

Örnek 6: Listelerle Çalışma

Makalenizde etiketler var ve belirli bir etiketin olup olmadığını kontrol etmek istiyorsunuz:

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

Döndürür: Makalede "featured" etiketi varsa true.

İlk etiketi alın:

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

Döndürür: İlk etiketi "announcement".

Etiketleri sayın:

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

Döndürür: Etiket sayısını 2.


Parametrik Rotalar ve meta.params

Parametrik rotalar, dinamik ve yerelleştirilmiş sayfalar oluşturmanın anahtarıdır. /{lang}/landingPage gibi bir rota deseni tanımladığınızda, CMS URL'den parametreleri çıkarır ve bunları meta.params aracılığıyla kullanılabilir hale getirir.

Rota Parametreleri Nasıl Çalışır

Rota Deseni Tanımı: Rotalar dinamik bölümler tanımlamak için :paramName veya {paramName} sözdizimini kullanır:

DesenÖrnek URLÇıkarılan Parametreler
/:lang/landingPage/ko/landingPage{ lang: "ko" }
/{country}/{lang}/products/us/en/products{ country: "us", lang: "en" }
/articles/:slug/articles/welcome-post{ slug: "welcome-post" }

Parametre Bağlamaları: Her rota parametresi doğrulama için bir belge şemasına bağlanabilir:

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

Bu bağlama CMS'ye şunu söyler:

  1. URL'den lang segmentini çıkar
  2. language şemasına göre doğrula (belgede content.code eşleşmesini arar)
  3. Geçerliyse, tamamen çözülmüş parametrede belgeyi kullanılabilir hale getir

Örnek: Dile Göre Açılış Sayfası

Rota yapılandırması:

  • Yol: /{lang}/landingPage
  • Desen: /{lang}/landingPage
  • Parametre bağlamaları: { "lang": "language" }

Karşılama belgeleriniz:

// greeting / ko
{ "code": "ko", "headline": "환영합니다", "subheadline": "우리 플랫폼에 오신 것을 환영합니다" }

// greeting / en
{ "code": "en", "headline": "Welcome", "subheadline": "Welcome to our platform" }

// greeting / ja
{ "code": "ja", "headline"

Yerelleştirilmiş içeriği getirmek için CEL betiği:

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

Nasıl çözülür:

URLmeta.params.langSonuç
/ko/landingPage"ko""환영합니다"
/en/landingPage"en""Welcome"
/ja/landingPage"ja""ようこそ"

Gelişmiş Desen: Ülke + Dil Rotaları

/{country}/{lang}/products gibi rotalar için:

Rota yapılandırması:

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

CEL betikleri:

// Ülke adını al
documents.get("country", meta.params.country).name

// Ülkeye göre yerelleştirilmiş ürün listesini al
documents.find("product", { "where": { "country": meta.params.country } })

// Birleştir: Kullanıcının dilinde ülkeye özel karşılama göster
documents.get("greeting", meta.params.lang).headline + " from " + documents.get("country", meta.params.country).name

Doğrulama zinciri: CMS parametreleri hiyerarşik olarak doğrular. /{country}/{lang} rotaları için:

  1. country parametresini country şemasına göre doğrular
  2. lang parametresini language şemasına göre doğrular
  3. İsteğe bağlı olarak lang değerinin country.languages[] dizisinde olup olmadığını kontrol eder (hiyerarşik doğrulama)

meta.segments - Ham URL Yolu Erişimi

meta.segments, adlandırılmış parametrelere ihtiyaç duymadan konumsal erişim gerektiğinde kullanışlı olan ham URL yolunu bir dizi olarak sağlar.

Nasıl çalışır:

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

meta.segments ne zaman, meta.params ne zaman?

Kullanım DurumuEn İyi Yaklaşım
Rota deseninden adlandırılmış parametrelermeta.params.lang
Konuma dayalı erişimmeta.segments[0]
Yol derinliğini almaksize(meta.segments)
Yol belirli bir segment içeriyor mu kontrolü"admin" in meta.segments

meta.segments ile örnekler

// İlk segmenti al (çoğunlukla dil kodu)
meta.segments[0]

// Yol derinliğini kontrol et
size(meta.segments) > 2 ? "deep" : "shallow"

// Yönetici bölümünde miyiz kontrol et
"admin" in meta.segments ? "admin mode" : "public mode"

// Yedek: Parametre bağlı değilse segmenti kullan
has(meta.params.lang) ? meta.params.lang : meta.segments[0]

meta Nesnesinin Tam Referansı

meta nesnesi, geçerli istekle ilgili tüm bağlamı içerir:

ÖzellikTürAçıklama
meta.localestringGeçerli yerel ayar kodu (ör. "en-US", "ko-KR", "ar-SA")
meta.paramsRecord<string, string>Rota deseninden çıkarılan URL parametreleri
meta.segmentsstring[]Segmentlere ayrılmış URL yolu
meta.docIdstring \\ | nullGeçerli belgenin UUID'si (yeni belgeler için null)
meta.titlestringGeçerli belgenin başlığı

meta.locale

Yerel ayar kodu BCP 47 biçimini (dil-bölge) izler:

// Sağdan sola dillere göre yerel ayarı kontrol et
meta.locale == "ar-SA" || meta.locale == "he-IL" ? "rtl" : "ltr"

// Yalnızca dil bölümünü al
meta.locale.split("-")[0]  // Desteklenmez - bunun yerine meta.params.lang kullanın

meta.params

Rota parametreleri her zaman stringtir. CMS, değerlendirmeden önce bunları bağlanan şemalara göre doğrular:

// Adlandırılmış parametreye eriş
meta.params.lang           // "ko"
meta.params.country        // "us"
meta.params.slug           // "welcome-post"

// Parametre var mı kontrol et
has(meta.params.category)  // true/false

// Belge getirmede kullanın
documents.get("greeting", meta.params.lang)
documents.ref("airports").get(meta.params.code)

meta.segments

Ham URL segmentleri bir dizi olarak:

// İndekse göre eriş (0 tabanlı)
meta.segments[0]           // İlk segment
meta.segments[1]           // İkinci segment

// Uzunluğu kontrol et
size(meta.segments)        // Segment sayısı

// Üyelik kontrolü
"products" in meta.segments  // Yolda "products" var mı?

meta.docId

Geçerli belgenin UUID'si, kendine referans veren betikler için kullanışlıdır:

// Yalnızca mevcut belgeleri düzenlerken kullanılabilir
meta.docId != null ? "editing" : "creating new"

// Koşullu mantıkta kullan
meta.docId != null ? documents.get("article", meta.docId).status : "draft"

meta.title

Geçerli belgenin başlığı:

// Görüntülemede kullan
"Editing: " + meta.title

// Başlığa göre koşul
meta.title.contains("Draft") ? "work in progress" : "published"

documents.ref() - Zincirleme Aramalar

Şemanın bilindiği ancak tanımlayıcının dinamik olduğu durumlarda daha temiz sözdizimi:

// Geleneksel yaklaşım
documents.get("airports", meta.params.code).name

// ref() kullanımı - şema dinamik tanımlayıcıdan ayrı
documents.ref("airports").get(meta.params.code).name

Her ikisi de eşdeğerdir, ancak ref() dinamik kısmı daha net hale getirir.


Hızlı Referans

Belge Getirme

documents.get("schema", "identifier")       // Tek bir belge getir
documents.get("schema", "id").fieldName     // Belirli bir alanı getir
documents.find("schema")                    // Tüm belgeleri getir
documents.find("schema", { "where": {...}}) // Filtrelenmiş sorgu
documents.ref("schema").get(identifier)     // Zincirleme arama

Bağlam Değişkenleri

meta.locale          // "en-US", "ar-SA" vb.
meta.params.xyz      // "xyz" adlı URL parametresi
meta.segments        // URL yolu dizi olarak: ["articles", "intro"]
meta.segments[0]     // İlk yol segmenti
meta.docId           // Geçerli belge kimliği (veya null)
meta.title           // Geçerli belgenin başlığı

Operatörler

// Karşılaştırma
==  !=  <  <=  >  >=

// Mantık
&&  ||  !

// Üçlü (if-else)
condition ? valueIfTrue : valueIfFalse

// Üyelik
"value" in listOrMap

Yaygın Fonksiyonlar

size(list)                    // Öğeleri say
size(string)                  // String uzunluğunu al
"text".startsWith("te")       // true
"text".endsWith("xt")         // true
"text".contains("ex")         // true
has(object.property)          // Özellik var mı kontrol et

Hata Mesajları

Bir şeyler ters giderse şu uyarılardan birini görürsünüz:

HataAnlamı
SYNTAX_ERRORBetiğinizde yazım hatası var (eksik tırnak, yanlış operatör)
TYPE_ERRORBirbiriyle çalışmayan türleri karıştırıyorsunuz
RUNTIME_ERRORBetik çalıştı ancak bir sorunla karşılaştı (tanımsız değişken)
FETCH_LIMIT_EXCEEDEDÇok fazla belge getiriyorsunuz (en fazla 50)
TIMEOUTBetik çok uzun sürdü (en fazla 5 saniye)
AST_DEPTH_EXCEEDEDİfade çok derin bir yapıya sahip (maksimum derinlik: 50)
SCRIPT_TOO_LONGBetik 5000 karakter sınırını aşıyor

Genişletilebilirlik ve Gelecek Yetkinlikler

CEL motoru genişletilebilir olacak şekilde tasarlanmıştır. Gelecekte planlanan yetenekler şunları içerir:

Planlanan: MCP Sunucu Entegrasyonu

// Gelecekte: MCP aracılığıyla harici servisleri çağır
mcp.translate(meta.params.text, "en", meta.params.lang)
mcp.analyze(documents.get("article", meta.params.id).body)

Planlanan: Yapay Zekâ Yetkinlikleri

// Gelecekte: Yapay zekâ destekli içerik üretimi
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"])

Bu yetenekler, geriye dönük uyumluluğu koruyarak kayıtlı fonksiyon sistemi aracılığıyla eklenecektir.


İpuçları

  1. Otomatik tamamlamayı kullanın - documents. veya meta. yazarak düzenleyicinin kullanılabilir seçenekleri göstermesini sağlayın
  2. Basit başlayın - Önce documents.get("schema", "id") ile test edin, sonra .fieldName ekleyin
  3. Null'a karşı kontrol edin - Belge olmayabilir, bu yüzden != null ? ... : ... ile yedek değer ekleyin
  4. Aşırı getirme yapmayın - Her documents.get() veya documents.find() çağrısı 50 getirme sınırına sayılır
  5. meta.params'i meta.segments'e tercih edin - Adlandırılmış parametreler doğrulanır ve daha güvenilirdir
  6. Opsiyonel parametreler için has() kullanın - meta.params.category'yi kullanmadan önce has(meta.params.category) ile kontrol edin
  7. Dinamik tanımlayıcılar için documents.ref() kullanın - Şema sabit, tanımlayıcı dinamik olduğunda daha açık sözdizimi sağlar

Ek A: Tam Parametrik Rota Örneği

Bu rehber, /{lang}/landingPage adresinden erişilebilen çok dilli bir açılış sayfası oluşturur.

Adım 1: Greeting Belge Şemasını Oluşturun

CMS yönetiminde greeting adlı özel bir şema oluşturun:

{
  "name": "greeting",
  "fields": [
    { "name": "code", "type": "string", "required": true },
    { "name": "headline", "type": "string", "required": true },
    { "name": "subheadline"

Adım 2: Greeting Belgelerini Oluşturun

Her dil için belgeler oluşturun:

Belge: greeting / ko

{
  "code": "ko",
  "headline": "환영합니다",
  "subheadline": "우리 플랫폼에 오신 것을 환영합니다",
  "ctaText": "시작하기",
  "ctaUrl": "/ko/get-started"
}

Belge: greeting / en

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

Belge: greeting / ja

{
  "code": "ja",
  "headline": "ようこそ",
  "subheadline": "私たちのプラットフォームへようこそ",
  "ctaText": "始める",
  "ctaUrl": "/ja/get-started"
}

Adım 3: Rotayı Oluşturun

Aşağıdaki yapılandırmaya sahip bir rota oluşturun:

  • Yol: /{lang}/landingPage
  • Desen: /{lang}/landingPage
  • Durum: Canlı
  • Parametre Bağlamaları:
  {
    "lang": "language"
  }

Adım 4: CEL Betikleriyle Bloklar Ekleyin

Rotaya bir hero bloğu ekleyin ve her alan için şu CEL betiklerini kullanın:

Başlık alanı:

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

Alt başlık alanı:

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

CTA Metni alanı:

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

CTA URL alanı:

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

Adım 5: Next.js'de Kullanın

Next.js uygulamanızda yakala-tüm rotası oluşturun:

// app/[...slug]/page.tsx
import { getCmsClient } from '@repo/renderer';

interface PageProps {
  params: { slug: string[] };
}

export default async function Page({ params }: PageProps) {

Adım 6: Rotaları Test Edin

Bu URL'leri ziyaret ederek yerelleştirilmiş içeriği görün:

URLBeklenen Başlık
/ko/landingPage환영합니다
/en/landingPageWelcome
/ja/landingPageようこそ

Çözüm Nasıl Çalışır

Bir kullanıcı /ko/landingPage adresini ziyaret ettiğinde:

  1. Rota Eşleşmesi: CMS /{lang}/landingPage desenini eşleştirir
  2. Parametre Çıkarımı: meta.params.lang = "ko"
  3. Doğrulama: CMS, "ko" değerinin language şemasında bulunduğunu doğrular
  4. CEL Değerlendirmesi: documents.get("greeting", meta.params.lang) gibi betikler Korece içeriğe çözülür
  5. Yanıt: Yerelleştirilmiş bloklar istemciye gönderilir

Ek B: Teknik Referans

CelMeta Arayüzü (TypeScript)

interface CelMeta {
  /** Geçerli yerel ayar kodu (örn. 'en-US') */
  locale: string;
  /** URL'den çıkarılan rota parametreleri */
  params: Record<string, string>;
  /** URL yolu segmentleri */
  segments: string[];
  /** Mevcut belge kimliği (varsa) */

Parametre Çıkarma Algoritması

extractParams fonksiyonu URL yollarını şöyle işler:

Pattern: /{country}/{lang}/products
Path:    /us/en/products

Algorithm:
1. Her ikisini normalleştir (sondaki eğik çizgileri kaldır)
2. Segmentlere ayır: ["us", "en", "products"] ve ["{country}", "{lang}", "products"

Desteklenen Parametre Bağlama Formatları

// Basit bağlama (arama için "code" alanını kullanır)
{ "lang": "language" }

// Ayrıntılı bağlama (özel slug alanı)
{
  "lang": {
    "schemaName": "language",
    "slugField": "code"
  },
  "slug": {
    "schemaName": "article",
    "slugField": "slug"
  }

Belge Arama Önceliği

documents.get(schema, identifier) ile getirirken öncelik sırası:

  1. UUID eşleşmesi: Tanımlayıcı geçerli bir UUID ise id ile getir
  2. Code alanı: content.code alanını kontrol et
  3. Slug alanı: content.slug alanını kontrol et
  4. Başlık eşleşmesi: title alanını kontrol et

Bu sayede belgeler, herhangi bir benzersiz tanımlayıcıyla esnek şekilde referans alınabilir.

]
] }
:
"ようこそ"
,
"subheadline"
:
"私たちのプラットフォームへようこそ"
}
,
"type"
:
"string"
},
{ "name": "ctaText", "type": "string" },
{ "name": "ctaUrl", "type": "string" }
]
}
const
client
=
getCmsClient
({
cmsUrl: process.env.CMS_URL!,
apiKey: process.env.CMS_API_KEY!,
websiteId: process.env.CMS_WEBSITE_ID!,
});
const path = '/' + params.slug.join('/');
// Rotayı ve çözülmüş parametreleri al
const { route, resolvedParams } = await client.routes.getRouteByPath.query({
websiteId: process.env.CMS_WEBSITE_ID!,
path,
});
// Rota için blokları al
const blocks = await client.blocks.getBlocks.query({
websiteId: process.env.CMS_WEBSITE_ID!,
blockIds: route.block_ids,
// CEL bağlamı için çözülmüş parametreleri ilet
context: {
meta: {
locale: resolvedParams?.lang?.document?.content?.code ?? 'en',
params: Object.fromEntries(
Object.entries(resolvedParams ?? {}).map(([k, v]) => [k, v.value])
),
segments: params.slug,
docId: null,
title: route.title ?? '',
},
schema: {},
},
});
// Blokları render et
return (
<main>
{blocks.map((block) => (
<BlockRenderer
key={block.id}
block={block}
routeParams={resolvedParams}
language={resolvedParams?.lang?.value}
/>
))}
</main>
);
}
docId
:
string
|
null
;
/** Mevcut belgenin başlığı */
title: string;
}
]
3. Segment sayılarını eşleştir (eşit olmalı)
4. Her segment çifti için:
- Desen : veya {} ile başlıyorsa parametre olarak çıkar
- Aksi hâlde tam eşleşme olmalı
5. Geri döndür: { country: "us", lang: "en" }
}