首先來了解一下 Sanity 的 schema
是如何定義的。
看看 sanity.config.ts
// ...
import {schemaTypes} from './schemaTypes'
export default defineConfig({
// ...
schema: {
types: schemaTypes,
},
})
可以看到它引入了 schemaTypes,再跟著來看看 schemaTypes/index.ts
:
export const schemaTypes = []
現在只有一個空陣列,有任何 schema 要定義的話都定義在這裡。
簡單建立個部落個文章的雛形。
一篇文章最基本一定會有標題跟內容:
export const schemaTypes = [
{
name: 'blogPost',
title: 'Blog Post',
type: 'document',
fields: [
{
name: 'title',
title: '標題',
type: 'string',
},
{
name: 'content',
title: '內容',
type: 'text',
},
],
},
]
可以看到我定義了一個型別為 document
的 Blog Post,
Blog Post 底下有兩個欄位,標題
、內容
,型別分別是 string
跟 text
。
定義後再去訪問 localhost:3333,會看到總算有內容了。
點擊建立後可以看到剛才定義的標題跟內容都出來了。並且隨著 type
的不同,欄位也有些許的不同。
type 有非常多種,有基本的 string
, number
, boolean
, image
, array
, object
等,更有特殊使用的 geopoint, url, span 等等,如果型別不夠使用還可以去找看看有沒有社群做好的 plugin 可以使用,要擴充是非常容易的。
Sanity 在資料型別上可以說是應有盡有。
至於 name
跟 title
的差別則是: title
是單純顯示給使用者看的,name
則是做為 API 的 key 使用,可以說是 name 比 title 重要很多哦!name 可得好好命名。
別忘了我開啟專案的時候使用的是 TypeScript,Sanity 對 schema 有提供一些 helper functions,讓在定義資料的時候可以知道哪些是必要屬性跟一些 autocomplete 的建議訊息。
可以從 sanity 中引入 defineType
或 defineField
之類的 helper functions 來輔助使用,這麼一來只要缺少必填欄位編輯器會馬上報錯,也會有一定程度的 autocomplete 功能,對於開發體驗會有很大的改善。
import {defineType, defineField} from 'sanity'
export const schemaTypes = [
defineType({
name: 'blogPost',
title: 'Blog Post',
type: 'document',
fields: [
defineField({
name: 'title',
title: '標題',
type: 'string',
}),
defineField({
name: 'content',
title: '內容',
type: 'text',
}),
],
}),
]
再來看一下一篇真正的文章,可能會需要什麼欄位:
看起來最基本會要有 標題
、網址
、副標題
、封面圖片
、內容
、發布日期
、標籤
。
用基本型別簡單寫下定義欄位:
import {defineType, defineField} from 'sanity'
export const schemaTypes = [
defineType({
name: 'blogPost',
title: 'Blog Post',
type: 'document',
fields: [
defineField({
name: 'title',
title: '標題',
type: 'string',
}),
defineField({
name: 'slug',
title: '網址',
type: 'string',
}),
defineField({
name: 'subtitle',
title: '副標題',
type: 'string',
}),
defineField({
name: 'heroImage',
title: '封面圖片',
type: 'image',
}),
defineField({
name: 'content',
title: '內容',
type: 'text',
}),
defineField({
name: 'publishedAt',
title: '發布日期',
type: 'date',
}),
defineField({
name: 'tags',
title: '標籤',
type: 'array',
of: [{type: 'string'}],
}),
],
}),
]
並且簡單寫上文章內容後:
資料定義完了,看起來也是還可以,簡單、明瞭對吧?
但好像還有些細節可以調整... 下一篇再說吧!