Astro 內容集合入門:構建強大的內容模型
本文節選自 SitePoint Premium 上現已發行的《釋放 Astro 的力量》一書。我們將學習如何利用 Astro 的內容集合功能構建靈活且可擴展的內容模型。
Astro 使用特殊的 src/content
文件夾來管理內容集合。您可以創建子文件夾來組織不同的內容集合,例如 src/content/dev-blog
和 src/content/corporate-blog
。
每個內容集合都可以在配置文件(例如 /src/content/config.js
或 .ts
)中進行配置,並使用 Zod 定義集合模式。 Zod 是一個“基於 TypeScript 的模式驗證工具,具有靜態類型推斷功能”,已集成到 Astro 中。
以下是一個配置示例:
<code class="language-javascript">// src/content/config.js import { z, defineCollection } from 'astro:content'; const devBlogCollection = defineCollection({ schema: z.object({ title: z.string(), author: z.string().default('The Dev Team'), tags: z.array(z.string()), date: z.date(), draft: z.boolean().default(true), description: z.string(), }), }); const corporateBlogCollection = defineCollection({ schema: z.object({ title: z.string(), author: z.string(), date: z.date(), featured: z.boolean(), language: z.enum(['en', 'es']), }), }); export const collections = { devblog: devBlogCollection, corporateblog: corporateBlogCollection, };</code>
代碼中定義了兩個內容集合:“開發者博客”和“企業博客”。 defineCollection
方法允許您為每個集合創建模式。
Markdown 文件和前端內容
本教程中的內容集合示例假設 .md
文件包含與配置文件中指定的模式匹配的前端內容。例如,一個“企業博客”文章可能如下所示:
<code class="language-markdown">--- title: 'Buy!!' author: 'Jack from Marketing' date: 2023-07-19 featured: true language: 'en' --- # Some Marketing Promo This is the best product!</code>
Slug 生成
Astro 會根據文件名自動生成文章的 slug。例如,first-post.md
的 slug 為 first-post
。如果在前端內容中提供 slug
字段,Astro 將使用自定義 slug。
請注意,export const collections
對像中指定的屬性必須與內容所在的文件夾名稱匹配(並且區分大小寫)。
數據查詢
準備好 Markdown 文件(位於 src/content/devblog
和 src/content/corporateblog
)和 config.js
文件後,您可以開始查詢集合中的數據:
<code class="language-javascript">--- import { getCollection } from 'astro:content'; const allDevPosts = await getCollection('devblog'); const allCorporatePosts = await getCollection('corporateblog'); --- {JSON.stringify(allDevPosts)} {JSON.stringify(allCorporatePosts)}</code>
getCollection
方法可用於檢索給定集合中的所有條目。示例中檢索了“開發者博客”(devblog
)和“企業博客”(corporateblog
)中的所有文章。模板中使用 JSON.stringify()
返回原始數據。
除了前端內容數據外,返回的數據還包含 id
、slug
和 body
屬性(body
屬性包含文章內容)。
您還可以通過迭代所有文章來過濾草稿或特定語言的文章:
<code class="language-javascript">import { getCollection } from 'astro:content'; const spanishEntries = await getCollection('corporateblog', ({ data }) => { return data.language === 'es'; });</code>
getCollection
返回所有文章,但您也可以使用 getEntry
返回集合中的單個條目:
<code class="language-javascript">import { getEntry } from 'astro:content'; const singleEntry = await getEntry('corporateblog', 'pr-article-1');</code>
getCollection
vs getEntries
雖然有兩種方法可以從集合中返回多篇文章,但兩者之間存在細微差別。 getCollection()
根據集合名稱檢索內容集合條目的列表,而 getEntries()
檢索來自同一集合的多個集合條目。
Astro 文檔中給出了 getEntries()
用於檢索內容的示例,其中使用了引用實體(例如,相關的文章列表)。
內容顯示
現在我們知道如何查詢數據,讓我們討論如何以格式化的方式顯示數據。 Astro 提供了一個名為 render()
的便捷方法,用於將 Markdown 的全部內容渲染到內置的 Astro 組件 <content></content>
中。構建和顯示內容的方式還取決於您使用的是靜態站點生成還是服務器端渲染模式。
對於預渲染,您可以使用 getStaticPaths()
方法:
<code class="language-javascript">// src/content/config.js import { z, defineCollection } from 'astro:content'; const devBlogCollection = defineCollection({ schema: z.object({ title: z.string(), author: z.string().default('The Dev Team'), tags: z.array(z.string()), date: z.date(), draft: z.boolean().default(true), description: z.string(), }), }); const corporateBlogCollection = defineCollection({ schema: z.object({ title: z.string(), author: z.string(), date: z.date(), featured: z.boolean(), language: z.enum(['en', 'es']), }), }); export const collections = { devblog: devBlogCollection, corporateblog: corporateBlogCollection, };</code>
代碼中使用了 getStaticPaths()
。然後依靠 Astro.props
來捕獲條目,該條目將是一個包含有關條目的元數據、id
、slug
和 render()
方法的對象。此方法負責將 Markdown 條目渲染到 Astro 模板中的 HTML,它通過創建 <content></content>
組件來實現。令人驚奇的是,現在您只需將 <content></content>
組件添加到模板中,即可看到渲染到 HTML 的 Markdown 內容。
以上是從Astro開始的內容收集開始的詳細內容。更多資訊請關注PHP中文網其他相關文章!