Astro 真正的王牌,不只是页面快,而是它对内容管理这件事做得非常顺。
它有一整套内容层心智:
- 内容不是随手
import一下就完 - 内容可以有结构
- 内容要有 schema
- 内容要能安全查询
- 内容和路由、渲染、类型系统最好连起来
这就是 content collections / content layer。
一个典型的内容配置:
// src/content.config.ts
import { defineCollection, reference, z } from 'astro:content';
import { glob } from 'astro/loaders';
const authors = defineCollection({
loader: glob({ pattern: '**/*.json', base: './src/data/authors' }),
schema: z.object({
name: z.string(),
role: z.string(),
avatar: z.string().optional(),
}),
});
const exhibitions = defineCollection({
loader: glob({ pattern: '**/*.md', base: './src/data/exhibitions' }),
schema: z.object({
title: z.string(),
summary: z.string(),
publishDate: z.coerce.date(),
cover: z.string(),
tags: z.array(z.string()).default([]),
author: reference('authors'),
}),
});
export const collections = { authors, exhibitions };然后在页面里查询:
---
import { getCollection } from 'astro:content';
const exhibitions = (await getCollection('exhibitions'))
.sort((a, b) => b.data.publishDate.getTime() - a.data.publishDate.getTime());
---
<ul>
{exhibitions.map((item) => (
<li>
<a href={`/exhibitions/${item.id}/`}>
{item.data.title}
</a>
<p>{item.data.summary}</p>
</li>
))}
</ul>把这套东西翻成展馆语言:
Collection = 某一类展品档案库
Schema = 每类展品必须填写的档案字段
getCollection() = 调出整库档案
getEntry() = 调出单件展品
reference() = 档案之间的关联索引
render() = 把展品正文真正展开成可展示内容这比“把 Markdown 文件当普通文件乱读一通”高了一个层级。