集合是 EmDash 內容模型的基礎。每個集合表示一種內容類型(文章、頁面、產品等),並包含決定資料形狀的欄位定義。
創建集合
在管理後台 內容類型 中創建集合。每個集合包含:
| 屬性 | 說明 |
|---|---|
slug | URL 安全標識(如 posts, products) |
label | 顯示名稱(如「Blog Posts」) |
labelSingular | 單數形式(如「Post」) |
description | 給編輯的可選說明 |
icon | 管理後台側欄用的 Lucide 圖標名 |
supports | 草稿、修訂、預覽、定時發布、搜索、SEO 等能力 |
集合能力
創建集合時可啟用所需能力。
| 能力 | 說明 |
|---|---|
drafts | 草稿/發布工作流 |
revisions | 用版本快照記錄內容歷史 |
preview | 為草稿生成帶籤名的預覽 URL |
scheduling | 預約未來時間發布 |
// 啟用全部能力的集合示例
{
slug: "posts",
label: "Blog Posts",
labelSingular: "Post",
supports: ["drafts", "revisions", "preview", "scheduling"]
}
欄位類型
EmDash 支持 15 種欄位類型,並映射到 SQLite 列類型。
文本
string
短文本輸入。映射到 TEXT 列。
{ slug: "title", type: "string", label: "Title" } text
多行文本區域。映射到 TEXT 列。
{ slug: "excerpt", type: "text", label: "Excerpt" } slug
URL 安全的 slug 欄位。映射到 TEXT 列。
{ slug: "handle", type: "slug", label: "URL Handle" } 富文本
portableText
富文本編輯器(TipTap/ProseMirror)。以 JSON 存儲。
{ slug: "content", type: "portableText", label: "Content" }Portable Text 為塊級格式,在不嵌入 HTML 的情況下保留結構。
json
任意 JSON 資料。以 JSON 存儲。
{ slug: "metadata", type: "json", label: "Custom Metadata" } 數值
number
小數。映射到 REAL 列。
{ slug: "price", type: "number", label: "Price" } integer
整數。映射到 INTEGER 列。
{ slug: "quantity", type: "integer", label: "Stock Quantity" } 布爾與日期時間
boolean
布爾開關。映射到 INTEGER(0/1)。
{ slug: "featured", type: "boolean", label: "Featured Post" } datetime
日期時間選擇器。以 ISO 8601 字符串存儲。
{ slug: "eventDate", type: "datetime", label: "Event Date" } 選擇
select
從列表中選一項。映射到 TEXT 列。
{
slug: "status",
type: "select",
label: "Product Status",
validation: {
options: ["active", "discontinued", "coming_soon"]
}
} multiSelect
從列表中選多項。以 JSON 數組存儲。
{
slug: "features",
type: "multiSelect",
label: "Product Features",
validation: {
options: ["wireless", "waterproof", "eco-friendly"]
}
} 媒體與引用
image
從媒體庫選圖。媒體 ID 存為 TEXT。
{ slug: "featuredImage", type: "image", label: "Featured Image" } file
從媒體庫選文件。媒體 ID 存為 TEXT。
{ slug: "attachment", type: "file", label: "PDF Attachment" } reference
引用另一集合中的條目。條目 ID 存為 TEXT。
{
slug: "author",
type: "reference",
label: "Author",
options: {
collection: "authors"
}
} 欄位屬性
所有欄位均可使用下列屬性。
| 屬性 | 類型 | 說明 |
|---|---|---|
slug | string | 資料庫列名 |
label | string | 管理後台 UI 顯示標籤 |
type | FieldType | 15 種欄位類型之一 |
required | boolean | 是否必填 |
unique | boolean | 是否要求在條目間唯一 |
defaultValue | unknown | 新條目的默認值 |
validation | object | 按類型的驗證規則 |
widget | string | 自定義小組件標識 |
options | object | 小組件專屬配置 |
sortOrder | number | 在編輯器中的顯示順序 |
驗證規則
validation 對象因欄位類型而異。
interface FieldValidation {
required?: boolean; // 所有類型
min?: number; // number, integer
max?: number; // number, integer
minLength?: number; // string, text
maxLength?: number; // string, text
pattern?: string; // string(正則)
options?: string[]; // select, multiSelect
}
帶驗證的示例:
{
slug: "email",
type: "string",
label: "Email Address",
required: true,
unique: true,
validation: {
pattern: "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
}
}
小組件選項
用 options 配置欄位專屬 UI 行為。
interface FieldWidgetOptions {
rows?: number; // text(textarea 行數)
showPreview?: boolean; // image, file
collection?: string; // reference(目標集合)
allowMultiple?: boolean; // reference(多選引用)
[key: string]: unknown; // 自定義小組件選項
}
引用欄位示例:
{
slug: "relatedProducts",
type: "reference",
label: "Related Products",
options: {
collection: "products",
allowMultiple: true
}
}
查詢集合
使用提供的查詢函數獲取內容。遵循 Astro Live Collections 模式,返回結構化結果。
import { getEmDashCollection, getEmDashEntry } from "emdash";
// 所有條目 — 返回 { entries, error }
const { entries: posts } = await getEmDashCollection("posts");
// 按狀態篩選
const { entries: drafts } = await getEmDashCollection("posts", {
status: "draft",
});
// 限制條數
const { entries: recent } = await getEmDashCollection("posts", {
limit: 5,
});
// 按分類法篩選
const { entries: newsPosts } = await getEmDashCollection("posts", {
where: { category: "news" },
});
// 按 slug 取一條 — 返回 { entry, error, isPreview }
const { entry: post } = await getEmDashEntry("posts", "my-post-slug");
// 錯誤處理
const { entries, error } = await getEmDashCollection("posts");
if (error) {
console.error("Failed to load posts:", error);
}
生成類型
npx emdash types 根據 schema 生成 TypeScript 類型。
// .emdash/types.ts(生成)
export interface Post {
title: string;
content: PortableTextBlock[];
excerpt?: string;
featuredImage?: string;
author: string; // 引用 ID
}
export interface Product {
title: string;
price: number;
description: PortableTextBlock[];
}
資料庫映射
欄位類型映射到 SQLite 列類型。
| 欄位類型 | SQLite 類型 | 備註 |
|---|---|---|
string | TEXT | |
text | TEXT | |
slug | TEXT | |
number | REAL | 64 位浮點 |
integer | INTEGER | 64 位有符號整數 |
boolean | INTEGER | 0 o 1 |
datetime | TEXT | ISO 8601 格式 |
select | TEXT | |
multiSelect | JSON | 字符串數組 |
portableText | JSON | 塊數組 |
image | TEXT | 媒體 ID |
file | TEXT | 媒體 ID |
reference | TEXT | 條目 ID |
json | JSON | 任意 JSON |