البدء
ثبت scribe-cms، وحدد مخططاً، واكتب المحتوى، ثم اقرأه بنوعه في خمس خطوات.
View as Markdownالتثبيت
pnpm add scribe-cms zod better-sqlite3
المتطلبات: Node 20+، و Zod v4. يعمل Scribe مع أي إطار عمل يعتمد على Node. يُعد better-sqlite3 وحدة أصلية، لذا يجب إبقاؤه خارج المجمّع الخاص بك (راجع صفحة واجهة برمجة تطبيقات وقت التشغيل).
1. إنشاء scribe.config.ts
ضعه في جذر مشروعك:
import { z } from "zod";
import { defineConfig, defineContentType, field } from "scribe-cms";
const blogSchema = z.object({
title: field.translatable(z.string().min(1)),
description: field.translatable(z.string().min(50).max(250)),
author: field.relation("author"),
tags: field.structural(z.array(z.string()).default([])),
});
const authorSchema = z.object({
name: field.structural(z.string().min(1)),
});
export default defineConfig({
rootDir: ".", // relative to this file (CLI) / process.cwd() (runtime)
locales: ["en", "fr", "de"],
types: [
defineContentType({
id: "blog",
path: "/blog/{slug}",
schema: blogSchema,
slugStrategy: "localized",
orderBy: "-publishedAt",
}),
defineContentType({
id: "author",
contentDir: "authors",
schema: authorSchema,
}),
],
});
يُعد كل من defineConfig و defineContentType دالتين متطابقتين تحافظان على الأنواع الحرفية، وهما ما يجعلان scribe.blog و related(doc, "author") محددين بالكامل لاحقاً.
2. كتابة المحتوى
content/
blog/
hello-world.mdx
authors/
jane.mdx
---
title: "مرحباً بالعالم"
description: "منشور أول يقول مرحباً للعالم، بإسهاب، لأن المخطط يتطلب خمسين حرفاً."
author: jane
publishedAt: "2026-01-15"
---
المحتوى هو MDX. يعمل كل من **Markdown** والمكونات.
اسم الملف (hello-world) هو المسار باللغة الإنجليزية. publishedAt هو أحد الحقول المضمنة المتاحة في كل نوع (راجع نموذج المحتوى).
3. التحقق
بعد pnpm install، يكون أمر scribe في مسار PATH الخاص بك (مثل next):
pnpm scribe validate
pnpm scribe status
أضفه قبل البناء:
{
"scripts": {
"build": "scribe validate && <your framework build>"
}
}
4. قراءة المحتوى
import { createScribe } from "scribe-cms/runtime";
import config from "./scribe.config";
const scribe = createScribe(config);
const posts = scribe.blog.list(); // BlogDoc[], newest first
const { document } = scribe.blog.resolve("hello-world", "fr");
const author = scribe.blog.related(document!, "author"); // AuthorDoc, non-null
يتم تحديد نوع document.frontmatter من مخطط Zod الخاص بك. راجع واجهة برمجة تطبيقات وقت التشغيل للحصول على التفاصيل الكاملة.
5. الترجمة
export GEMINI_API_KEY=... # or put it in .env
npx scribe translate --locale fr
يبحث Scribe عن كل صفحة مفقودة أو قديمة باللغة الفرنسية، ويترجم الحقول التي حددتها كـ field.translatable()، ويخزن النتيجة في .scribe/store.sqlite. احفظ هذا الدليل، ولا تضف .scribe/ أبداً إلى .gitignore. التفاصيل في الترجمة.
).