跳转到内容

集合与字段

集合是 EmDash 内容模型的基础。每个集合代表一种内容类型(如文章、页面、产品),并包含用于确定数据结构的字段定义。

通过管理面板的 内容类型 部分创建集合。每个集合包含:

EmDash 内容类型展示页面、文章和自定义集合及其功能
属性描述
slugURL 安全标识符(例如 posts、products)
label显示名称(例如 “博客文章”)
labelSingular单数形式(例如 “文章”)
description面向编辑者的可选描述
icon管理侧边栏使用的 Lucide 图标名称
supports支持的功能,如草稿、修订、预览、定时发布、搜索、SEO

创建集合时,启用你需要的功能:

功能描述
drafts启用草稿/已发布工作流
revisions通过版本快照跟踪内容历史
preview为草稿内容生成带签名的预览 URL
scheduling安排内容在未来日期发布
// Example collection with all features enabled
{
slug: "posts",
label: "Blog Posts",
labelSingular: "Post",
supports: ["drafts", "revisions", "preview", "scheduling"]
}

EmDash 支持 15 种字段类型,它们映射到 SQLite 列类型:

短文本输入。映射到 TEXT 列。

{ slug: "title", type: "string", label: "Title" }

富文本编辑器(TipTap/ProseMirror)。以 JSON 格式存储。

{ slug: "content", type: "portableText", label: "Content" }

Portable Text 是一种基于块的格式,无需嵌入 HTML 即可保留结构。

十进制数字。映射到 REAL 列。

{ slug: "price", type: "number", label: "Price" }

真/假切换。映射到 INTEGER(0/1)。

{ slug: "featured", type: "boolean", label: "Featured Post" }

从列表中选择单个选项。映射到 TEXT 列。

{
slug: "status",
type: "select",
label: "Product Status",
validation: {
options: ["active", "discontinued", "coming_soon"]
}
}

从媒体库中选择图片。将媒体 ID 存储为 TEXT。

{ slug: "featuredImage", type: "image", label: "Featured Image" }

每个字段都支持以下属性:

属性类型描述
slugstring数据库中的列名
labelstring管理界面中的显示标签
typeFieldType15 种字段类型之一
requiredboolean字段是否必须具有值
uniqueboolean值在条目间是否必须唯一
defaultValueunknown新条目的默认值
validationobject特定于类型的验证规则
widgetstring自定义小部件标识符
optionsobject小部件特定配置
sortOrdernumber编辑器中的显示顺序

validation 对象因字段类型而异:

interface FieldValidation {
required?: boolean; // All types
min?: number; // number, integer
max?: number; // number, integer
minLength?: number; // string, text
maxLength?: number; // string, text
pattern?: string; // string (regex)
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 rows)
showPreview?: boolean; // image, file
collection?: string; // reference (target collection)
allowMultiple?: boolean; // reference (multiple refs)
[key: string]: unknown; // Custom widget options
}

引用字段示例:

{
slug: "relatedProducts",
type: "reference",
label: "Related Products",
options: {
collection: "products",
allowMultiple: true
}
}

使用提供的查询函数来获取内容。这些函数遵循 Astro 的实时集合模式,返回结构化结果:

import { getEmDashCollection, getEmDashEntry } from "emdash";
// Get all entries - returns { entries, error }
const { entries: posts } = await getEmDashCollection("posts");
// Filter by status
const { entries: drafts } = await getEmDashCollection("posts", {
status: "draft",
});
// Limit results
const { entries: recent } = await getEmDashCollection("posts", {
limit: 5,
});
// Filter by taxonomy
const { entries: newsPosts } = await getEmDashCollection("posts", {
where: { category: "news" },
});
// Get a single entry by slug - returns { entry, error, isPreview }
const { entry: post } = await getEmDashEntry("posts", "my-post-slug");
// Handle errors
const { entries, error } = await getEmDashCollection("posts");
if (error) {
console.error("Failed to load posts:", error);
}

运行 npx emdash types 以根据你的模式生成 TypeScript 类型:

// .emdash/types.ts (generated)
export interface Post {
title: string;
content: PortableTextBlock[];
excerpt?: string;
featuredImage?: string;
author: string; // reference ID
}
export interface Product {
title: string;
price: number;
description: PortableTextBlock[];
}

字段类型映射到 SQLite 列类型:

字段类型SQLite 类型备注
stringTEXT
textTEXT
slugTEXT
numberREAL64 位浮点数
integerINTEGER64 位有符号整数
booleanINTEGER0 或 1
datetimeTEXTISO 8601 格式
selectTEXT
multiSelectJSON字符串数组
portableTextJSON块数组
imageTEXT媒体 ID
fileTEXT媒体 ID
referenceTEXT条目 ID
jsonJSON任意 JSON