الإعدادات
كل خيارات `scribe.config.ts`: إعدادات المشروع، وأنواع المحتوى، وعلامات الحقول، وتوجيه اللغات.
View as Markdownيوجد كل شيء في ملف واحد هو scribe.config.ts، والذي يصدر defineConfig({...}). يقرأ كل من وقت التشغيل (createScribe) وواجهة سطر الأوامر CLI (التي تكتشف scribe.config.ts في دليل العمل) نفس الملف.
خيارات المشروع
export default defineConfig({
rootDir: ".",
contentDir: "content", // default
store: ".scribe/store.sqlite", // default
assetsDir: "public", // optional
locales: ["en", "fr", "de"],
defaultLocale: "en", // default
localeRouting: { strategy: "path-prefix", prefixDefaultLocale: false },
localeFallbacks: true, // default
localePresets: { active: ["fr"] },
translate: { /* see the translation page */ },
types: [ /* defineContentType(...) */ ],
});
| الخيار | الافتراضي | الوصف |
|---|---|---|
rootDir | — (مطلوب) | جذر المشروع. اجعله نسبياً (عادة "."): تقوم واجهة سطر الأوامر بحله بناءً على مسار مجلد ملف الإعدادات، بينما يحله createScribe بناءً على process.cwd(). لا تقم ببنائه من import.meta.url لأن حزم التجميع تقوم بتضمين هذا المسار أثناء البناء، مما يتسبب في تعطله على استضافات بدون خادم مثل Vercel. |
contentDir | "content" | المجلد الذي يحتوي على مجلد واحد لكل نوع من أنواع المحتوى. |
store | ".scribe/store.sqlite" | مخزن ترجمة SQLite. قم بحفظه (Commit)؛ ولا تتجاهل .scribe/ في Git. |
assetsDir | — | الجذر الخاص بالملفات الثابتة (مثل "public"). عند ضبطه، يُصدر scribe validate تحذيراً بشأن مسارات الصور في الواجهة الأمامية للمستند أو النصوص التي لا وجود لها على القرص. |
locales | — (مطلوب) | جميع اللغات، بما فيها اللغة الافتراضية. |
defaultLocale | "en" | اللغة الأساسية المعتمدة. يجب أن تكون ضمن قائمة locales. |
localeRouting | path-prefix، افتراضي بلا بادئة | كيفية ظهور علامات اللغات في الروابط (URLs) المنشأة. الخيار path-prefix يسبق المسار برمز اللغة (مع استثناء اللغة الافتراضية ما لم يكن prefixDefaultLocale مفعّلاً). الخيار search-param يضيف ?param=locale للغات غير الافتراضية. |
localeFallbacks | true | اشتقاق سلاسل اللغات البديلة من وسوم اللغات: إذا كان هناك نسخة إقليمية تفتقر لترجمة مستند ما، يتم عرض الترجمة الأقرب للغة الأساسية (مثل pt-BR تعود إلى pt) قبل العودة إلى اللغة الافتراضية. عيِّنه على false لتعطيله. راجع سلاسل اللغات البديلة. |
localePresets | — | مجموعات اللغات المسماة لاستخدامها مع scribe translate --preset name. |
translate | — | الإعدادات الافتراضية للترجمة على مستوى المشروع (الترجمة). |
types | — (مطلوب) | تعريفات أنواع المحتوى. |
يتم التحقق من صحة الإعدادات مقدماً: في حال وجود defaultLocale غير معروف، أو معرفات أنواع مكررة، أو قالب path غير صالح، يتم إطلاق خطأ فوراً برسالة واضحة.
خيارات نوع المحتوى
defineContentType({
id: "blog",
schema: blogSchema,
path: "/blog/{slug}",
contentDir: "blog", // default: the id
slugStrategy: "localized", // default: "fixed"
indexFallback: "en", // default: "en" if path is set, else "none"
orderBy: "-publishedAt", // default: "slug"
label: "Blog", // default: capitalized id (studio UI only)
crossValidate: (data, ctx) => [],
translate: { /* per-type overrides */ },
})
| الخيار | الوصف |
|---|---|
id | معرف فريد. يصبح هو طريقة الوصول المكتوبة (scribe.blog) وcontentDir الافتراضي. |
schema | مخطط كائن Zod للواجهة الأمامية للمستند (frontmatter)، مزوداً بعلامات الحقول (انظر أدناه). |
path | قالب الرابط مع {slug} واحد فقط (مثل /blog/{slug}). تجنب استخدامه مع الأنواع المخصصة كمراجع فقط (مثل المؤلفين أو الفئات) التي ليس لها صفحات خاصة بها. |
contentDir | المجلد الموجود داخل contentDir الخاص بالمشروع، والذي يحتوي على ملفات .mdx لهذا النوع. |
slugStrategy | "fixed": تستخدم جميع اللغات الاسم اللطيف (slug) الإنجليزي. "localized": يُنشئ المترجم اسماً لطيفاً لكل لغة على حدة (/fr/blog/bonjour-le-monde). |
indexFallback | ما يُرجعه resolve() عندما لا تتوفر ترجمة للغة معينة: الخيار "en" يعرض المستند الإنجليزي (مع actualLocale: "en")، والخيار "none" لا يُرجع شيئاً. |
orderBy | طريقة الفرز الافتراضية للدالة list(): إما "slug"، أو "publishedAt"، أو "-publishedAt"، أو "updatedAt"، أو "-updatedAt"، أو دالة مقارنة (a, b) => number على المستندات المكتوبة بالكامل. |
crossValidate | تحقق إضافي يتم تشغيله بواسطة scribe validate، ويستقبل البيانات المحللة من الواجهة الأمامية للمستند. يجب أن يُرجع [{ field, message, level }]. |
translate | موجّه/قواعد/نموذج الترجمة المخصص لكل نوع محتوى (الترجمة). |
علامات الحقول
كل حقل في المخطط يندرج تحت واحد من ثلاثة أنواع. وتُعتبر الحقول غير المعلمة هيكلية كخيار افتراضي.
import { field } from "scribe-cms";
const schema = z.object({
// Sent to the translator, stored per locale:
title: field.translatable(z.string().min(1)),
// English-only; copied from the EN document into every locale:
heroImage: field.structural(z.string().optional()),
// English slug reference(s) to another content type:
author: field.relation("author"),
relatedPosts: field.relation("blog", { multiple: true, max: 4, optional: true }),
});
تعمل علامات الحقول القابلة للترجمة أيضاً على الحقول المتداخلة داخل المصفوفات العادية أو الكائنات (مثل sections.*.title)؛ كل ما عليك هو ألا تغلف المصفوفة الحاوية بـ field.structural، وإلا فستصبح الشجرة الفرعية بأكملها باللغة الإنجليزية فقط.
الدالة field.relation(typeId, options?)
| الخيار | الافتراضي | الوصف |
|---|---|---|
multiple | false | يشير إلى أن الحقل عبارة عن مصفوفة من الأسماء اللطيفة (slugs). |
optional | false | يمكن تجاهل هذا الحقل. وفي هذه الحالة، يُرجع related() القيمة null (للأفراد) أو يتجاوز العناصر المفقودة (للمتعدد). |
min / max | — | حدود عدد العناصر (يُستخدم فقط مع multiple: true). |
تُوضع القيود في كائن الخيارات، وليس في دوال Zod المتسلسلة. فاستخدام التسلسل (مثل .max(8) أو .optional()) يقوم باستنساخ المخطط وبالتالي إزالة البيانات الوصفية للعلاقة.
تحتفظ العلاقات دائماً بـ الأسماء اللطيفة (slugs) الإنجليزية، ويتم التحقق منها بواسطة scribe validate (تُعد العلاقة المطلوبة المفقودة خطأ يمنع البناء؛ بينما تُعد العلاقة الاختيارية المفقودة تحذيراً)، ويتم فك مرجعيتها أثناء وقت التشغيل باستخدام related()؛ راجع واجهة برمجة تطبيقات وقت التشغيل.
سلاسل اللغات البديلة
افتراضياً، إذا كانت هناك لغة إقليمية تفتقر لترجمة مستند ما، فسيتم تقديم لغتها الأساسية قبل اللغة الافتراضية: حيث تجرب كل لغة البادئات الأقصر المتعاقبة للوسم الخاص بها والموجودة ضمن locales، لذا فإن fr-CA تعود إلى fr، وzh-Hant-TW تجرب zh-Hant ثم zh. عيِّن localeFallbacks: false لتعطيل هذه الميزة. ولا تكون اللغة الافتراضية أبداً جزءاً من هذه السلسلة؛ بل تظل هي البديل النهائي الذي يتحكم فيه خيار indexFallback الخاص بالنوع.
تنطبق اللغات البديلة على الدالة resolve() (حيث يتم الإبلاغ عن اللغة المعروضة في actualLocale، وتستخدم عمليات إعادة التوجيه للأسماء اللطيفة الاسم الخاص باللغة البديلة) وعلى staticParams() (تتطابق الأسماء اللطيفة المُصيَّرة مسبقاً مع ما تعرضه resolve()). وبشكل متعمد، لا تنطبق هذه اللغات البديلة على get() أو list() أو translation() أو alternates() أو خريطة الموقع sitemap: حيث تظل هذه تعتمد على التطابق التام.
الأنواع الصارمة للعميل
بالنسبة للأسماء المستعارة للأنواع على مستوى التطبيق، قم باشتقاق كل شيء من الإعدادات:
import type { ScribeClient, ScribeDocs } from "scribe-cms/runtime";
import config from "./scribe.config";
type MyScribe = ScribeClient<typeof config>;
type BlogDoc = ScribeDocs<typeof config>["blog"];