iT邦幫忙

2024 iThome 鐵人賽

DAY 3
0

Sanity schema

首先來了解一下 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 底下有兩個欄位,標題內容,型別分別是 stringtext

定義後再去訪問 localhost:3333,會看到總算有內容了。
https://ithelp.ithome.com.tw/upload/images/20240917/20101989VXZvhn2c0Q.png

點擊建立後可以看到剛才定義的標題跟內容都出來了。並且隨著 type 的不同,欄位也有些許的不同。
type 有非常多種,有基本的 string, number, boolean, image, array, object 等,更有特殊使用的 geopoint, url, span 等等,如果型別不夠使用還可以去找看看有沒有社群做好的 plugin 可以使用,要擴充是非常容易的。

Sanity 在資料型別上可以說是應有盡有。

至於 nametitle 的差別則是: title 是單純顯示給使用者看的,name 則是做為 API 的 key 使用,可以說是 name 比 title 重要很多哦!name 可得好好命名。


加上 TypeScript

別忘了我開啟專案的時候使用的是 TypeScript,Sanity 對 schema 有提供一些 helper functions,讓在定義資料的時候可以知道哪些是必要屬性跟一些 autocomplete 的建議訊息。

可以從 sanity 中引入 defineTypedefineField 之類的 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',
      }),
    ],
  }),
]

再來看一下一篇真正的文章,可能會需要什麼欄位:

https://ithelp.ithome.com.tw/upload/images/20240917/20101989U4s8WQPGSF.png

https://ithelp.ithome.com.tw/upload/images/20240917/20101989EF6Vz0SMeM.png

看起來最基本會要有 標題網址副標題封面圖片內容發布日期標籤

用基本型別簡單寫下定義欄位:

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'}],
      }),
    ],
  }),
]

並且簡單寫上文章內容後:
https://ithelp.ithome.com.tw/upload/images/20240917/201019898pWinRruCm.png

資料定義完了,看起來也是還可以,簡單、明瞭對吧?

但好像還有些細節可以調整... 下一篇再說吧!


上一篇
Day 2 - Sanity 安裝與配置
下一篇
Day 4 - Sanity preview 設定
系列文
用 Sanity 跟 Nextjs 重寫個人部落格30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言