先拿一張 Sanity 官方的圖片
可以看到 preview 分為三個部分。
所以設計 preview 就是要怎麼用這三個欄位清楚表達每筆資料。
再來看一下一個沒有特別設定的資料資料會怎麼顯示:
可以看得出來 Sanity 預設會自己去猜欄位,但可能不是我們想要的。
我想要的是:
先用基本的 preview 來設定:
export const schemaTypes = [
defineType({
// ...
preview: {
select: {
title: 'title',
subtitle: 'subtitle',
media: 'heroImage',
},
},
fields: [
defineField({
name: 'title',
title: '標題',
type: 'string',
}),
// ...
defineField({
name: 'subtitle',
title: '副標題',
type: 'string',
}),
defineField({
name: 'heroImage',
title: '封面圖片',
type: 'image',
}),
]
}),
]
看 preview.select
那邊的定義,透過定義 title
, subtitle
跟 media
就可以用欄位的 name 告訴 Sanity 要顯示的分別對應在哪個的 。
像上面定義告訴 media 要顯示 heroImage 欄位的圖片。
簡單的定義,標題、副標題跟圖片都有了。
但是要顯示的 subtitle 應該要是發布日期跟標籤才對。
// ...
preview: {
select: {
title: 'title',
date: 'publishedAt',
media: 'heroImage',
tags: 'tags',
},
prepare(selection) {
const {title, tags = [], date, media} = selection
return {
title,
subtitle: `${date} - ${tags.join(', ')}`,
media,
}
},
},
// ...
組簡單的組合 subtitle 字串就完成了。
那縮圖要顯示的話可以改用 JSX
來寫。
首先,把 blogPost 拉出一個檔案叫 schemaTypes/blogPost.tsx
import {defineType, defineField} from 'sanity'
export default defineType({
name: 'blogPost',
title: 'Blog Post',
type: 'document',
preview: {
select: {
title: 'title',
date: 'publishedAt',
media: 'heroImage',
tags: 'tags',
},
prepare(selection) {
const {title, tags = [], date, media} = selection
return {
title,
subtitle: `${date} - ${tags.join(', ')}`,
media,
}
},
},
fields: [
// ...
],
})
基本上就是把 blogPost 定義直接複製過來,再引入回 schemaTypes/index.ts
import blogPost from './blogPost'
export const schemaTypes = [
blogPost,
]
接下來來簡單做一下
// ...
preview: {
select: {
title: 'title',
date: 'publishedAt',
media: 'heroImage',
tags: 'tags',
},
prepare(selection) {
const {title, tags = [], date, media} = selection
return {
title,
subtitle: `${date} - ${tags.join(', ')}`,
media: media || <span>❔❔</span>,
}
},
},
// ...
判斷沒有 media 就使用 <span>❔❔</span>
來替代。
Preview 就到這邊吧!!