视频地址:https://www.bilibili.com/video/BV1qY4y1K7AH/
Sanity 建模
官网及文档: https://www.sanity.io/
yarn add sanity@dev-preview sanity-plugin-markdown@studio-v3
yarn add @sanity/client
创建一个 Sanity 配置文件 sanity.config.ts :
import { createConfig } from 'sanity';
import { deskTool } from 'sanity/desk';
import { markdownSchema } from 'sanity-plugin-markdown';
export default createConfig({
name: 'default',
title: 'willin.wang',
projectId: 'crrougir',
dataset: 'production',
plugins: [deskTool(), markdownSchema()],
schema: {
types: [
{
title: 'Post',
name: 'post',
type: 'document',
fields: [
{
name: 'title',
title: 'Title',
type: 'string'
},
{
name: 'slug',
title: 'Slug',
type: 'slug',
options: {
source: 'title'
}
},
{
name: 'content',
title: 'Content',
type: 'markdown'
},
{
name: 'excerpt',
title: 'Excerpt',
type: 'string'
},
{
title: 'Tags',
name: 'tags',
type: 'array',
of: [
{
type: 'reference',
to: [{ type: 'tag' }]
}
]
},
{
name: 'lang',
title: 'Language',
type: 'string',
initialValue: 'zhCN'
}
]
},
{
name: 'tag',
title: 'Tag',
type: 'document',
fields: [
{
name: 'name',
title: 'Name',
type: 'object',
fields: [
{
name: 'zhCN',
title: '简体中文',
type: 'string'
},
{
name: 'enUS',
title: 'English',
type: 'string'
}
]
},
{
name: 'slug',
title: 'Slug',
type: 'slug',
options: {
source: 'title'
}
}
]
}
]
}
});
该配置文件包含:
后续还需要根据文章类型再加上:页面、文章、代码片段的区分(做视频的时候忘了)。
本地启动 sanity 服务:
npx sanity start
然后访问: http://localhost:3333 登录并管理内容。
Sanity 客户端调用封装
import createClient from '@sanity/client';
const sanityConfig = {
projectId: process.env.SANITY_PROJECT_ID || 'crrougir',
dataset: process.env.SANITY_DATASET || 'production',
useCdn: process.env.NODE_ENV !== 'production',
apiVersion: '2021-03-25'
};
export const sanityClient = createClient(sanityConfig);
export const previewClient = createClient({
...sanityConfig,
useCdn: false,
token: process.env.SANITY_API_TOKEN
});
export const getClient = (preview) => (preview ? previewClient : sanityClient);
因为默认允许有两个 dataset,其中一个为 Production,所以可以使用 previewClient 来访问开发环境。
Sanity 查询
GROQ 查询语言: https://www.sanity.io/docs/groq
需要好好看看,折腾了半天没太搞明白。好不容易凑了一个例子跑对了。
const postFields = `
_id,
title,
excerpt,
lang,
tags[]->{
name,
"slug": slug.current
},
"slug": slug.current,
`;
export const postQuery = `
{
"post": *[_type == "post" && slug.current == $slug] | order(_updatedAt desc) [0] {
content,
${postFields}
}
}`;
注意 tags 那里,折腾了好久。
写一个测试接口:
import { json } from '@remix-run/node';
import { postQuery } from '~/lib/query';
import { getClient } from '~/lib/sanity';
export const loader = async () => {
const data = await getClient().fetch(postQuery, { slug: 'test' });
return json(data);
};
|