定义内容合集
内容合集是内容优先应用中管理和创作内容的最佳方式。Velite 能帮助您组织和验证内容,并通过自动类型生成提供类型安全性。
什么是内容合集?
内容合集 是一组相关内容项的集合。例如,一个博客可能包含 文章 合集、作者 合集和 标签 合集。
每个合集应放置在项目 content 目录中的顶级目录中。
content
├── authors # => authors 合集
│ ├── zce.yml
│ └── jane.yml
├── posts # => posts 合集
│ ├── hello-world.md
│ └── another-post.md
└── tags # => tags 合集
└── all-in-one.yml每个合集都由一个模式(schema)定义,该模式描述了合集中内容项的结构。
import { defineCollection, defineConfig, s } from 'velite'
const posts = defineCollection({
/* 合集模式选项 */
})
const authors = defineCollection({
/* 合集模式选项 */
})
const tags = defineCollection({
/* 合集模式选项 */
})
export default defineConfig({
collections: { authors, posts, tags }
})合集模式选项
name
合集的名称。用于生成合集的类型名称。
const posts = defineCollection({
name: 'Post'
})类型名称通常是单数名词,但也可以是任何有效的 TypeScript 标识符。
pattern
用于查找合集内容文件的 glob 模式。
const posts = defineCollection({
pattern: 'posts/**/*.md'
// or pattern: ['posts/**/*.md', '!posts/private/**']
})Velite 使用 fast-glob 来查找内容文件,因此您可以使用 fast-glob 支持的任何 glob 模式。
默认情况下,Velite 会忽略以 _ 或 . 开头的文件和目录。
single
是否应将合集视为单一项。这对于只有一个内容项的合集非常有用,例如站点的元数据。
const site = defineCollection({
pattern: 'site/index.yml',
single: true
})schema
Velite 使用 Zod 来验证合集的内容项。schema 选项用于定义用于验证合集中内容项的 Zod 模式。
要在 Velite 中使用 Zod,请从 'velite' 导入 z 实用工具。这是 Zod 的 z 对象的重新导出,它支持 Zod 的所有功能。有关 Zod 的工作原理和可用功能的完整文档,请参阅 Zod 文档。
import { z } from 'velite'
const posts = defineCollection({
schema: z.object({
title: z.string().max(99)
})
})TIP
模式通常是一个 ZodObject,用于验证内容项的结构。但它也可以是任何有效的 Zod 模式。
对于更复杂的模式,建议使用 Velite 扩展模式 s:
s.slug():验证 slug 格式,在文章合集中保持唯一。s.isodate():将日期字符串格式化为 ISO 日期字符串。s.unique():验证合集中的唯一值。s.image():输入图片相对路径,输出包含模糊图片的对象。s.file():输入文件相对路径,输出文件公共路径。s.metadata():提取 Markdown 的阅读时间、字数统计等元数据。s.excerpt():Markdown 内容的摘要。s.markdown():将 Markdown 转换为 HTML。s.mdx():将 MDX 转换为函数代码。
例如:
import { s } from 'velite'
const posts = defineCollection({
schema: s.object({
slug: s.slug('posts'),
date: s.isodate(),
cover: s.image(),
video: s.file().optional(),
metadata: s.metadata(),
excerpt: s.excerpt(),
content: s.markdown()
})
})有关 Velite 扩展字段模式的更多信息,请参阅 Velite 模式。
模式转换(计算字段)
可以使用 .transform() 方法转换 Zod 模式。这对于向合集中的内容项添加计算字段非常有用。
const posts = defineCollection({
schema: s
.object({
slug: s.slug('posts')
})
.transform(data => ({
...data,
// 计算字段
permalink: `/blog/${data.slug}`
}))
})转换上下文元数据
transform() 函数可以接收第二个参数,即上下文对象。这对于向合集中的内容项添加计算字段非常有用。
const posts = defineCollection({
schema: s
.object({
// 字段
})
.transform((data, { meta }) => ({
...data,
// 计算字段
path: meta.path // 或基于文件名的 slug 解析
}))
})meta 的类型是 ZodMeta,它扩展了 VeliteFile。更多信息,请参阅 自定义模式。
内容正文
Velite 的内置加载器将内容的原始正文保留在 meta.content 中,纯文本正文保留在 meta.plain 中。
要将它们添加为字段,可以使用自定义模式。
const posts = defineCollection({
schema: s.object({
content: s.custom().transform((data, { meta }) => meta.content),
plain: s.custom().transform((data, { meta }) => meta.plain)
})
})TIP
这将保留原始文档正文。在大多数情况下,应使用 s.markdown() / s.mdx() 模式来转换文档正文。
Markdown 与 MDX
除了验证合集中的内容项之外,Velite 还可以使用 Unified 处理内容正文。
const posts = defineCollection({
schema: s.object({
content: s.markdown() // 或 s.mdx()
})
})content 字段将从 markdown 转换为 html,结果将在内容项的 content 字段中可用。
参考
元数据
Velite 可以从内容文件中提取元数据。这对于向合集中的内容项添加计算字段非常有用。
const posts = defineCollection({
schema: s.object({
metadata: s.metadata() // 提取 Markdown 的阅读时间、字数统计等元数据
})
})参考
摘要
Velite 可以从内容文件中提取摘要。这对于向合集中的内容项添加计算字段非常有用。
const posts = defineCollection({
schema: s.object({
excerpt: s.excerpt({ length: 200 }) // markdown 正文的摘要
})
})