Kontent.ai 与 Astro
Kontent.ai 是一个无头 CMS,它允许你以结构化和模块化的方式管理内容,并得到人工智能功能的支持。
与 Astro 集成
Section titled “与 Astro 集成”在这个部分中,你将使用 Kontent.ai TypeScript SDK 将你的 Kontent.ai 项目连接到 Astro 应用程序。
在开始之前,你需要以下内容:
-
Kontent.ai 项目 - 如果你还没有 Kontent.ai 账号,可以 免费注册 并创建一个新项目。
-
Delivery API 密钥 - 你需要已发布内容的环境 ID 和用于获取草稿的预览 API 密钥(可选)。这两个密钥位于 Kontent.ai 的 Settings -> API Keys 选项卡中。
为了将你的 Kontent.ai 凭据添加到 Astro,你需要在项目的根目录下创建一个名为 .env 的文件,并添加以下变量:
KONTENT_ENVIRONMENT_ID=YOUR_ENVIRONMENT_IDKONTENT_PREVIEW_API_KEY=YOUR_PREVIEW_API_KEY这样,这些环境变量就可以在你的 Astro 项目中使用了。
如果你想要获得这些环境变量的 TypeScript IntelliSense,你可以在 src/ 目录下创建一个新的 env.d.ts 文件,并像下面这样配置 ImportMetaEnv:
interface ImportMetaEnv { readonly KONTENT_ENVIRONMENT_ID: string; readonly KONTENT_PREVIEW_API_KEY: string;}现在,你的根目录应该包含这些新文件:
文件夹src/
- env.d.ts
- .env
- astro.config.mjs
- package.json
要将 Astro 连接到你的 Kontent.ai 项目,请安装 Kontent.ai TypeScript SDK:
npm install @kontent-ai/delivery-sdk pnpm add @kontent-ai/delivery-sdk yarn add @kontent-ai/delivery-sdk接下来,在 Astro 项目的 src/lib/ 目录中创建一个名为 kontent.ts 的新文件。
import { createDeliveryClient } from "@kontent-ai/delivery-sdk";
export const deliveryClient = createDeliveryClient({ environmentId: import.meta.env.KONTENT_ENVIRONMENT_ID, previewApiKey: import.meta.env.KONTENT_PREVIEW_API_KEY,});请阅读更多有关 在 Astro 中获取环境变量 的内容。
该实现将使用 .env 文件中的凭据创建一个新的 DeliveryClient 对象。
previewApiKey 是可选的。当它被使用时,你可以为 配置每个查询 所指向的 Delivery API 端点,以返回内容项的最新版本,而不考虑其在工作流中的状态。否则,只返回已发布的内容项。
最后,你的 Astro 项目的根目录现在应该包含这些新文件:
文件夹src/
文件夹lib/
- kontent.ts
- env.d.ts
- .env
- astro.config.mjs
- package.json
现在,DeliveryClient 对象对所有组件都可用了。要获取内容,请使用 DeliveryClient 和方法链来定义你想要的项。以下示例展示了获取博客文章,并将它们的标题渲染为列表的基础代码:
---import { deliveryClient } from "../lib/kontent";
const blogPosts = await deliveryClient .items() .type("blogPost") .toPromise()---<html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width" /> <title>Astro</title> </head> <body> <ul> {blogPosts.data.items.map(blogPost => ( <li>{blogPost.elements.title.value}</li> ))} </ul> </body></html>你可以在 Kontent.ai 文档 中找到更多的查询选项。
使用 Astro 和 Kontent.ai 创建博客
Section titled “使用 Astro 和 Kontent.ai 创建博客”通过上述设置,你现在可以创建一个使用 Kontent.ai 作为内容源的博客。
-
Kontent.ai 项目 - 对于本教程,建议使用一个空白项目。如果你的内容模型中已经有一些内容类型,你可以使用它们,但需要修改代码片段以匹配你的内容模型。
-
已配置从 Kontent.ai 获取内容的 Astro 项目 - 有关如何设置使用 Kontent.ai 的 Astro 项目的详细信息,请参阅上文。
设置内容模型
Section titled “设置内容模型”在 Kontent.ai 中,转到 Content model 并创建一个新的内容类型,具有以下字段和值:
- Name: Blog Post
- Elements:
- Text field
- Name: Title
- Element Required: yes
- Rich text field
- Name: Teaser
- Element Required: yes
- Allowed in this element: only check Text
- Rich text field
- Name: Content
- Element Required: yes
- Date & time field
- Name: Date
- URL slug field
- Name: URL slug
- Element Required: yes
- Auto-generate from: select “Title”
- Text field
接着,点击 Save Changes。
现在,转到 Content & assets 选项卡,并创建一个新的 Blog Post 类型的内容项。使用以下值填写字段:
- Content item name: Astro
- Title: Astro is amazing
- Teaser: Astro is an all-in-one framework for building fast websites faster.
- Content: You can use JavaScript to implement the website functionality, but no client bundle is necessary.
- Date & time: select today
- URL slug: astro-is-amazing
完成后,使用顶部的 Publish 按钮发布博客文章。
注意:在进行下一步之前,你可以随意创建任意数量的博客文章。
在 TypeScript 中生成内容模型
Section titled “在 TypeScript 中生成内容模型”接下来,你将从你的内容模型中生成 TypeScript 类型。
这一步是可选的,但它可以提供更好的开发者体验,并允许你在构建时发现潜在问题,而不是在运行时。
首先,安装 Kontent.ai JS 模型生成器、ts-node 和 dotenv:
npm install @kontent-ai/model-generator ts-node dotenv pnpm add @kontent-ai/model-generator ts-node dotenv yarn add @kontent-ai/model-generator ts-node dotenv接着,将如下脚本添加到 package.json 中:
{ ... "scripts": { ... "regenerate:models": "ts-node --esm ./generate-models.ts" },}由于类型需要关于你项目的结构信息,而这些信息在公共 API 中是不暴露的,因此你还需要将一个 Content Management API 密钥添加到 .env 文件中。你可以在 Environment settings -> API keys -> Management API 下生成该密钥。
KONTENT_ENVIRONMENT_ID=YOUR_ENVIRONMENT_IDKONTENT_PREVIEW_API_KEY=YOUR_PREVIEW_API_KEYKONTENT_MANAGEMENT_API_KEY=YOUR_MANAGEMENT_API_KEY最后,添加配置用于生成模型的模型生成器脚本 generate-models.ts:
import { generateModelsAsync, textHelper } from '@kontent-ai/model-generator'import { rmSync, mkdirSync } from 'fs'
import * as dotenv from 'dotenv'dotenv.config()
const runAsync = async () => { rmSync('./src/models', { force: true, recursive: true }) mkdirSync('./src/models')
// 修改对应模型的工作目录 process.chdir('./src/models')
await generateModelsAsync({ sdkType: 'delivery', apiKey: process.env.KONTENT_MANAGEMENT_API_KEY ?? '', environmentId: process.env.KONTENT_ENVIRONMENT_ID ?? '', addTimestamp: false, isEnterpriseSubscription: false, })}
// 自调用的异步函数;(async () => { await runAsync()})().catch(err => { console.error(err) throw err})现在,你可以执行命令了:
npm run regenerate:models pnpm run regenerate:models yarn run regenerate:models展示博客文章列表
Section titled “展示博客文章列表”现在你已经准备好获取一些内容了。进入你想要显示博客文章列表的 Astro 页面,例如 src/pages 目录下的首页 index.astro。
在 Astro 页面的 frontmatter 中获取所有博客文章:
---import { deliveryClient } from '../lib/kontent';import type { BlogPost } from '../models';import { contentTypes } from '../models/project/contentTypes';
const blogPosts = await deliveryClient .items<BlogPost> .type(contentTypes.blog_post.codename) .toPromise()---如果你跳过了模型生成,也可以使用未经类型定义的对象和字符串字面量来定义类型:
const blogPosts = await deliveryClient .items() .type("blogPost") .toPromise()fetch 调用将返回一个包含所有博客文章的列表的 response 对象,这些内容保存在 data.items 中。在 Astro 页面的 HTML 部分,你可以使用 map() 函数列出所有博客文章:
---import { deliveryClient } from '../lib/kontent';import type { BlogPost } from '../models';import { contentTypes } from '../models/project/contentTypes';
const blogPosts = await deliveryClient .items<BlogPost> .type(contentTypes.blogPost.codename) .toPromise()---<html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width" /> <title>Astro</title> </head> <body> <h1>Blog posts</h1> <ul> {blogPosts.data.items.map(blogPost => ( <li> <a href={`/blog/${blogPost.elements.url_slug.value}/`} title={blogPost.elements.title.value}> {blogPost.elements.title.value} </a> </li> ))} </ul> </body></html>