内容集
Added in:
astro@2.0.0
内容集合是管理和编写任何 Astro 项目中内容的最佳方式。集合有助于组织文档、验证 frontmatter 并为所有内容提供自动 TypeScript 类型安全。
¥Content collections are the best way to manage and author content in any Astro project. Collections help to organize your documents, validate your frontmatter, and provide automatic TypeScript type-safety for all of your content.
什么是内容集?
Section titled 什么是内容集?¥What are Content Collections?
内容集合是保留的 src/content
项目目录内的任何顶层目录,例如 src/content/newsletter
和 src/content/authors
。src/content
目录中仅允许内容集合。该目录不能用于其他任何用途。
¥A content collection is any top-level directory inside the reserved src/content
project directory, such as src/content/newsletter
and src/content/authors
. Only content collections are allowed inside the src/content
directory. This directory cannot be used for anything else.
集合条目是存储在内容集合目录内的任何内容。条目可以使用内容创作格式,包括 Markdown (.md
) 和 MDX(.mdx
使用 MDX 集成)或作为两种受支持的数据格式之一:YAML (.yaml
) 和 JSON (.json
)。我们建议为你的文件使用一致的命名方案(小写、破折号而不是空格),以便更轻松地查找和组织你的内容,但这不是必需的。你还可以通过在文件名前添加下划线 (_) 来进行 从构建中排除条目。
¥A collection entry is any piece of content stored inside of your content collection directory. Entries can use content authoring formats including Markdown (.md
) and MDX (.mdx
using the MDX integration) or as one of two supported data formats: YAML (.yaml
) and JSON (.json
). We recommend using a consistent naming scheme (lower-case, dashes instead of spaces) for your files to make it easier to find and organize your content, but this is not required. You can also exclude entries from being built by prefixing the filename with an underscore (_).
Directorysrc/content/
Directorynewsletter/ the “newsletter” collection
- week-1.md a collection entry
- week-2.md a collection entry
- week-3.md a collection entry
一旦你有了集合,你就可以使用 Astro 的内置内容 API 启动 查询你的内容。
¥Once you have a collection, you can start querying your content using Astro’s built-in content APIs.
“.astro” 目录
Section titled “.astro” 目录¥The “.astro” Directory
Astro 将内容集合的重要元数据存储在项目的 .astro
目录中。你无需执行任何操作即可维护或更新此目录。我们鼓励你在项目中工作时完全忽略它。
¥Astro stores important metadata for content collections in an .astro
directory in your project. No action is needed on your part to maintain or update this directory. You are encouraged to ignore it entirely while working in your project.
每当你运行 astro dev
、astro build
命令时,.astro
目录都会自动更新。你可以随时运行 astro sync
来手动更新 .astro
目录。
¥The .astro
directory will be updated for you automatically anytime you run the astro dev
, astro build
commands. You can run astro sync
at any time to update the .astro
directory manually.
组织多个集合
Section titled 组织多个集合¥Organizing with multiple collections
如果两个文件代表不同类型的内容(例如博客文章和作者简介),它们很可能属于不同的集合。这很重要,因为许多功能(frontmatter 验证、自动 TypeScript 类型安全)要求集合中的所有条目共享相似的结构。
¥If two files represent different kinds of content (e.g. a blog post and an author profile), they most likely belong in different collections. This is important because many features (frontmatter validation, automatic TypeScript type-safety) require that all entries in a collection share a similar structure.
如果你发现自己正在处理不同类型的内容,则应该创建多个集合来表示每种类型。你可以根据需要在项目中创建任意数量的不同集合。
¥If you find yourself working with different types of content, you should create multiple collections to represent each type. You can create as many different collections in your project as you’d like.
Directorysrc/content/
Directorynewsletter/
- week-1.md
- week-2.md
Directoryblog/
- post-1.md
- post-2.md
Directoryauthors/
- grace-hopper.json
- alan-turing.json
使用子目录进行组织
Section titled 使用子目录进行组织¥Organizing with subdirectories
内容集合始终是 src/content/
目录内的顶层文件夹。你不能将一个集合嵌套在另一个集合中。但是,你可以使用子目录来组织集合中的内容。
¥A content collection is always a top-level folder inside of the src/content/
directory. You cannot nest one collection inside of another. However, you can use subdirectories to organize your content within a collection.
例如,你可以使用以下目录结构在单个 docs
集合中组织 i18n 翻译。当你查询此集合时,你将能够使用文件路径按语言过滤结果。
¥For example, you can use the following directory structure to organize i18n translations within a single docs
collection. When you query this collection, you’ll be able to filter the result by language using the file path.
Directorysrc/content/
Directorydocs/ this collection uses subdirectories to organize by language
Directoryen/
- …
Directoryes/
- …
Directoryde/
- …
¥Defining Collections
要充分利用你的内容集合,请在项目中创建 src/content/config.ts
文件(还支持 .js
和 .mjs
扩展名)。这是一个特殊文件,Astro 将自动加载并使用它来配置你的内容集合。
¥To get the most out of your content collections, create a src/content/config.ts
file in your project (.js
and .mjs
extensions are also supported.) This is a special file that Astro will automatically load and use to configure your content collections.
设置 TypeScript
Section titled 设置 TypeScript¥Setting up TypeScript
如果你尚未在 tsconfig.json
文件中扩展 Astro 的 strict
或 strictest
推荐的 TypeScript 设置,则可能需要更新 tsconfig.json
以启用 strictNullChecks
。
¥If you do not already extend Astro’s strict
or strictest
recommended TypeScript settings in your tsconfig.json
file, you may need to update your tsconfig.json
to enable strictNullChecks
.
如果你在 Astro 项目中使用 .js
或 .mjs
文件,则可以通过在 tsconfig.json
中启用 allowJs
来启用 IntelliSense 并在编辑器中进行类型检查:
¥If you use .js
or .mjs
files in an Astro project, you can enable IntelliSense and type checking in your editor by enabling allowJs
in your tsconfig.json
:
定义集合模式
Section titled 定义集合模式¥Defining a collection schema
模式强制集合中一致的前题或条目数据。模式保证当你需要引用或查询此数据时,它以可预测的形式存在。如果任何文件违反其集合架构,Astro 将提供有用的错误来通知你。
¥Schemas enforce consistent frontmatter or entry data within a collection. A schema guarantees that this data exists in a predictable form when you need to reference or query it. If any file violates its collection schema, Astro will provide a helpful error to let you know.
模式还为 Astro 的内容自动 TypeScript 类型提供支持。当你为集合定义架构时,Astro 将自动生成 TypeScript 接口并将其应用到其中。当你查询集合时,结果是完整的 TypeScript 支持,包括属性自动补齐和类型检查。
¥Schemas also power Astro’s automatic TypeScript typings for your content. When you define a schema for your collection, Astro will automatically generate and apply a TypeScript interface to it. The result is full TypeScript support when you query your collection, including property autocompletion and type-checking.
要定义你的第一个集合,请创建一个 src/content/config.ts
文件(如果尚不存在)(还支持 .js
和 .mjs
扩展名。)此文件应该:
¥To define your first collection, create a src/content/config.ts
file if one does not already exist (.js
and .mjs
extensions are also supported.) This file should:
- 从
astro:content
导入适当的实用程序。 - 定义你想要验证的每个集合。这包括
type
(在 Astro v2.5.0 中引入),指定集合是否包含 Markdown (type: 'content'
) 等内容创作格式或 JSON 或 YAML (type: 'data'
) 等数据格式。它还包括一个schema
,用于定义 frontmatter 或条目数据的形状。 - 导出单个
collections
对象以注册你的集合。
定义多个集合
Section titled 定义多个集合¥Defining multiple collections
你可以根据需要多次使用 defineCollection()
以创建多个模式。所有集合必须从单个 collections
对象内部导出。
¥You can use defineCollection()
as many times as you want to create multiple schemas. All collections must be exported from inside the single collections
object.
随着项目的发展,你还可以自由地重新组织代码库并将逻辑移出 src/content/config.ts
文件。单独定义架构对于跨多个集合重用架构以及与项目的其他部分共享架构非常有用。
¥As your project grows, you are also free to reorganize your codebase and move logic out of the src/content/config.ts
file. Defining your schemas separately can be useful for reusing schemas across multiple collections and sharing schemas with other parts of your project.
使用第三方集合模式
Section titled 使用第三方集合模式¥Using third-party collection schemas
你可以从任何地方导入集合架构,包括外部 npm 包。当使用提供自己的集合架构供你使用的主题和库时,这非常有用。
¥You can import collection schemas from anywhere, including external npm packages. This can be useful when working with themes and libraries that provide their own collection schemas for you to use.
使用 Zod 定义数据类型
Section titled 使用 Zod 定义数据类型¥Defining datatypes with Zod
Astro 使用 佐德 来支持其内容模式。借助 Zod,Astro 能够验证集合中每个文件的 frontmatter,并在你从项目内部查询内容时提供自动 TypeScript 类型。
¥Astro uses Zod to power its content schemas. With Zod, Astro is able to validate every file’s frontmatter within a collection and provide automatic TypeScript types when you go to query content from inside your project.
要在 Astro 中使用 Zod,请从 "astro:content"
导入 z
实用程序。这是 Zod 库的重新导出,它支持 Zod 的所有功能。有关 Zod 如何工作以及可用功能的完整文档,请参阅 Zod 的自述文件。
¥To use Zod in Astro, import the z
utility from "astro:content"
. This is a re-export of the Zod library, and it supports all of the features of Zod. See Zod’s README for complete documentation on how Zod works and what features are available.
定义集合引用
Section titled 定义集合引用¥Defining collection references
集合条目还可以 “reference” 其他相关条目。
¥Collection entries can also “reference” other related entries.
使用 Collections API 中的 reference()
函数,你可以将集合架构中的属性定义为另一个集合中的条目。例如,你可以要求每个 space-shuttle
条目都包含一个 pilot
属性,该属性使用 pilot
集合自己的架构进行类型检查、自动补齐和验证。
¥With the reference()
function from the Collections API, you can define a property in a collection schema as an entry from another collection. For example, you can require that every space-shuttle
entry includes a pilot
property which uses the pilot
collection’s own schema for type checking, autocomplete, and validation.
一个常见的示例是引用以 JSON 形式存储的可重用作者个人资料或存储在同一集合中的相关帖子 URL 的博客文章:
¥A common example is a blog post that references reusable author profiles stored as JSON, or related post URLs stored in the same collection:
此示例博客文章指定相关帖子的 slug
和帖子作者的 id
:
¥This example blog post specifies the slug
s of related posts and the id
of the post author:
定义自定义段
Section titled 定义自定义段¥Defining custom slugs
使用 type: 'content'
时,每个内容条目都会从其 文件 id
生成 URL 友好的 slug
属性。slug 用于直接从你的集合中查询条目。当从你的内容创建新页面和 URL 时,它也很有用。
¥When using type: 'content'
, every content entry generates a URL-friendly slug
property from its file id
. The slug is used to query the entry directly from your collection. It is also useful when creating new pages and URLs from your content.
你可以通过将你自己的 slug
属性添加到文件 frontmatter 来覆盖条目生成的 slug。这与其他 Web 框架的 “permalink” 功能类似。"slug"
是一个特殊的保留属性名称,在你的自定义集合 schema
中不允许使用,并且不会出现在你条目的 data
属性中。
¥You can override an entry’s generated slug by adding your own slug
property to the file frontmatter. This is similar to the “permalink” feature of other web frameworks. "slug"
is a special, reserved property name that is not allowed in your custom collection schema
and will not appear in your entry’s data
property.
¥Querying Collections
Astro 提供了两个函数来查询集合并返回一个(或多个)内容条目:getCollection()
和 getEntry()
。
¥Astro provides two functions to query a collection and return one (or more) content entries: getCollection()
and getEntry()
.
这两个函数都返回 CollectionEntry
类型定义的内容条目。
¥Both functions return content entries as defined by the CollectionEntry
type.
访问参考数据
Section titled 访问参考数据¥Accessing referenced data
首次查询你的集合条目后,必须单独查询任何 架构中定义的引用。你可以再次使用 getEntry()
函数或 getEntries()
,从返回的 data
对象中检索引用的条目。
¥Any references defined in your schema must be queried separately after first querying your collection entry. You can use the getEntry()
function again, or getEntries()
, to retrieve the referenced entry from the returned data
object.
过滤集合查询
Section titled 过滤集合查询¥Filtering collection queries
getCollection()
采用可选的 “filter” 回调,允许你根据条目的 id
或 data
(frontmatter)属性过滤查询。对于 type: 'content'
的集合,你还可以根据 slug
进行过滤。
¥getCollection()
takes an optional “filter” callback that allows you to filter your query based on an entry’s id
or data
(frontmatter) properties. For collections of type: 'content'
, you can also filter based on slug
.
你可以使用它来按你喜欢的任何内容标准进行过滤。例如,你可以按 draft
等属性进行过滤,以防止任何草稿博客文章发布到你的博客:
¥You can use this to filter by any content criteria you like. For example, you can filter by properties like draft
to prevent any draft blog posts from publishing to your blog:
你还可以创建在运行开发服务器时可用但不在生产中构建的草稿页面:
¥You can also create draft pages that are available when running the dev server, but not built in production:
filter 参数还支持按集合中的嵌套目录进行过滤。由于 id
包含完整的嵌套路径,因此你可以按每个 id
的开头进行过滤,以仅返回特定嵌套目录中的项目:
¥The filter argument also supports filtering by nested directories within a collection. Since the id
includes the full nested path, you can filter by the start of each id
to only return items from a specific nested directory:
使用 Astro 模板中的内容
Section titled 使用 Astro 模板中的内容¥Using content in Astro templates
查询集合条目后,你可以直接在 Astro 组件模板内访问每个条目。这可让你呈现 HTML,例如指向内容的链接(使用内容 slug
)或有关内容的信息(使用 data
属性)。
¥Once you have queried your collection entries, you can access each entry directly inside of your Astro component template. This lets you render HTML for things like links to your content (using the content slug
) or information about your content (using the data
property).
有关将内容渲染为 HTML 的信息,请参阅下面的 将内容渲染为 HTML。
¥For information about rendering your content to HTML, see Rendering Content to HTML below.
将内容作为属性传递
Section titled 将内容作为属性传递¥Passing content as props
组件还可以将整个内容条目作为 prop 传递。
¥A component can also pass an entire content entry as a prop.
如果这样做,你可以使用 CollectionEntry
实用程序使用 TypeScript 正确键入组件属性。该实用程序采用与集合架构名称匹配的字符串参数,并将继承该集合架构的所有属性。
¥If you do this, you can use the CollectionEntry
utility to correctly type your components props using TypeScript. This utility takes a string argument that matches the name of your collection schema, and will inherit all of the properties of that collection’s schema.
将内容渲染为 HTML
Section titled 将内容渲染为 HTML¥Rendering content to HTML
查询后,你可以使用条目 render()
函数属性将 Markdown 和 MDX 条目渲染为 HTML。调用此函数使你可以访问渲染的内容和元数据,包括 <Content />
组件和所有渲染的标题的列表。
¥Once queried, you can render Markdown and MDX entries to HTML using the entry render()
function property. Calling this function gives you access to rendered content and metadata, including both a <Content />
component and a list of all rendered headings.
从内容生成路由
Section titled 从内容生成路由¥Generating Routes from Content
内容集合存储在 src/pages/
目录之外。这意味着默认情况下不会为你的集合项生成任何路由。你将需要手动创建一个新的 动态路由 以从你的集合条目生成 HTML 页面。你的动态路由将映射传入的请求参数(例如:src/pages/blog/[...slug].astro
中的 Astro.params.slug
)以获取集合内的正确条目。
¥Content collections are stored outside of the src/pages/
directory. This means that no routes are generated for your collection items by default. You will need to manually create a new dynamic route to generate HTML pages from your collection entries. Your dynamic route will map the incoming request param (ex: Astro.params.slug
in src/pages/blog/[...slug].astro
) to fetch the correct entry inside a collection.
生成路由的确切方法将取决于你的构建 output
模式:‘static’(默认值)或 ‘server’(对于 SSR)。
¥The exact method for generating routes will depend on your build output
mode: ‘static’ (the default) or ‘server’ (for SSR).
构建静态输出(默认)
Section titled 构建静态输出(默认)¥Building for static output (default)
如果你正在构建静态网站(Astro 的默认行为),你将在构建过程中使用 getStaticPaths()
函数从单个 src/pages/
组件创建多个页面。
¥If you are building a static website (Astro’s default behavior), you would use the getStaticPaths()
function to create multiple pages from a single src/pages/
component during your build.
在 getStaticPaths()
到 查询你的内容或数据集合 中调用 getCollection()
。然后,使用每个内容条目的 slug
属性(内容集合)或 id
属性(数据集合)创建新的 URL 路径。
¥Call getCollection()
inside of getStaticPaths()
to query your content or data collection. Then, create your new URL paths using the slug
property (content collections) or id
property (data collections) of each content entry.
这将为 blog
集合中的每个条目生成一个新页面。例如,src/content/blog/hello-world.md
处的条目将具有 hello-world
的段,因此其最终 URL 将为 /posts/hello-world/
。
¥This will generate a new page for every entry in the blog
collection. For example, an entry at src/content/blog/hello-world.md
will have a slug of hello-world
, and therefore its final URL will be /posts/hello-world/
.
构建服务器输出 (SSR)
Section titled 构建服务器输出 (SSR)¥Building for server output (SSR)
如果你正在构建动态网站(使用 Astro 的 SSR 支持),则不需要在构建过程中提前生成任何路径。相反,你的页面应该检查请求(使用 Astro.request
或 Astro.params
)以按需查找 slug
,然后使用 getEntry()
获取它。
¥If you are building a dynamic website (using Astro’s SSR support), you are not expected to generate any paths ahead of time during the build. Instead, your page should examine the request (using Astro.request
or Astro.params
) to find the slug
on-demand, and then fetch it using getEntry()
.
从基于文件的路由迁移
Section titled 从基于文件的路由迁移¥Migrating from File-Based Routing
如果你现有的 Astro 项目(例如博客)在 src/pages/
内的子文件夹中使用 Markdown 或 MDX 文件,请考虑将相关内容或数据文件迁移到内容集合。
¥If you have an existing Astro project, such as a blog, that uses Markdown or MDX files in subfolders inside src/pages/
, consider migrating related content or data files to content collections.
了解如何在使用 构建博客教程的已完成项目 代码库的 分步教程 中将基本博客示例从 src/pages/posts/
转换为 src/content/posts
。
¥See how to convert a basic blog example from src/pages/posts/
to src/content/posts
in our step-by-step tutorial that uses the codebase from the Build a Blog tutorial’s finished project.
启用 JSON 模式生成
Section titled 启用 JSON 模式生成¥Enabling JSON Schema Generation
Added in:
astro@4.13.0
如果你正在使用 data
类型的集合,Astro 将自动生成 JSON 模式文件,以供你的编辑器获取 IntelliSense 和类型检查。将根据你在 src/content/config.ts
中定义的集合,使用名为 zod-to-json-schema
的库为项目中的每个数据集合创建一个单独的文件。
¥If you are working with collections of type data
, Astro will auto-generate JSON schema files for your editor to get IntelliSense and type-checking. A separate file will be created for each data collection in your project based on your collections defined in src/content/config.ts
using a library called zod-to-json-schema
.
此功能要求你手动将架构的文件路径设置为集合中每个数据输入文件中 $schema
的值:
¥This feature requires you to manually set your schema’s file path as the value for $schema
in each data entry file of the collection:
或者,你可以在编辑器设置中设置此值。例如,要在 VSCode 的 json.schemas
设置 中设置此值,请提供要匹配的文件路径和 JSON 模式的位置:
¥Alternatively, you can set this value in your editor settings. For example, to set this value in VSCode’s json.schemas
setting, provide the path of files to match and the location of your JSON schema:
启用构建缓存
Section titled 启用构建缓存¥Enabling Build Caching
Added in:
astro@3.5.0
Experimental
如果你正在处理大型集合,你可能希望使用 experimental.contentCollectionCache
标志启用缓存构建。这一实验性功能优化了 Astro 的构建过程,使未更改的集合能够在构建之间存储和重用。
¥If you are working with large collections, you may wish to enable cached builds with the experimental.contentCollectionCache
flag. This experimental feature optimizes Astro’s build process, enabling unchanged collections to be stored and reused between builds.
在许多情况下,这可以显着提高构建性能。
¥In many cases, this can lead to significant build performance improvements.
虽然此功能稳定下来,但你可能会遇到存储缓存的问题。你始终可以通过运行以下命令来重置构建缓存:
¥While this feature stabilizes, you may run into issues with the stored cache. You can always reset your build cache by running the following command:
使用 Remark 修改 Frontmatter
Section titled 使用 Remark 修改 Frontmatter¥Modifying Frontmatter with Remark
Astro 支持 直接修改你的 frontmatter.0 的评论或 rehype 插件。你可以使用从 render()
返回的 remarkPluginFrontmatter
属性来访问内容条目中修改后的 frontmatter:
¥Astro supports remark or rehype plugins that modify your frontmatter directly. You can access this modified frontmatter inside of a content entry by using the remarkPluginFrontmatter
property returned from render()
:
评论和 rehype 管道仅在渲染内容时运行,这解释了为什么 remarkPluginFrontmatter
仅在你对内容条目调用 render()
后才可用。相反,getCollection()
和 getEntry()
无法直接返回这些值,因为它们不渲染你的内容。
¥The remark and rehype pipelines only run when your content is rendered, which explains why remarkPluginFrontmatter
is only available after you call render()
on your content entry. In contrast, getCollection()
and getEntry()
cannot return these values directly because they do not render your content.
在 frontmatter 中处理日期
Section titled 在 frontmatter 中处理日期¥Working with dates in the frontmatter
内容集合中可以使用多种日期格式,但集合的架构必须与 Markdown 或 MDX YAML frontmatter 中使用的格式匹配。
¥Several date formats are possible in content collections, but your collection’s schema must match the format used in your Markdown or MDX YAML frontmatter.
YAML 使用 ISO-8601 标准来表达日期。使用格式 yyyy-mm-dd
(例如 2021-07-28
)以及架构类型 z.date()
:
¥YAML uses the ISO-8601 standard to express dates. Use the format yyyy-mm-dd
(e.g. 2021-07-28
) along with a schema type of z.date()
:
如果未提供时区,则日期格式将以 UTC 格式指定。如果需要指定时区,可以使用 ISO 8601 格式。
¥The date format will be specified in UTC if a timezone is not provided. If you need to specify a timezone, you can use the ISO 8601 format.
要仅渲染完整 UTC 时间戳中的 YYYY-MM-DD
,请使用 JavaScript slice
方法删除时间戳:
¥To render only the YYYY-MM-DD
from the full UTC timestamp, use the JavaScript slice
method to remove the timestamp:
要查看使用 toLocaleDateString
来格式化日、月和年的示例,请参阅官方 Astro 博客模板中的 <FormattedDate />
组件。
¥To see an example of using toLocaleDateString
to format the day, month, and year instead, see the <FormattedDate />
component in the official Astro blog template.