iT邦幫忙

2024 iThome 鐵人賽

DAY 4
0

先拿一張 Sanity 官方的圖片
https://ithelp.ithome.com.tw/upload/images/20240918/20101989Mp4XLTdUSI.png

可以看到 preview 分為三個部分。

  • title
  • subtitle
  • media

所以設計 preview 就是要怎麼用這三個欄位清楚表達每筆資料。


再來看一下一個沒有特別設定的資料資料會怎麼顯示:

https://ithelp.ithome.com.tw/upload/images/20240918/20101989FCfk8U1git.png

可以看得出來 Sanity 預設會自己去猜欄位,但可能不是我們想要的。
我想要的是:

  • title - 目前這樣就好
  • subtitle - 顯示發布日期、標籤
  • media - 沒有圖片的時候可以顯示預設圖片

Sanity Preview 基本使用

先用基本的 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, subtitlemedia 就可以用欄位的 name 告訴 Sanity 要顯示的分別對應在哪個的 。
像上面定義告訴 media 要顯示 heroImage 欄位的圖片。

https://ithelp.ithome.com.tw/upload/images/20240918/20101989UXWv3NGpmS.png

簡單的定義,標題、副標題跟圖片都有了。


但是要顯示的 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> 來替代。

https://ithelp.ithome.com.tw/upload/images/20240918/20101989uSTjfPHlKG.png


Preview 就到這邊吧!!


上一篇
Day 3 - Sanity 資料型別規劃
下一篇
Day 5 - Sanity Validation ( 欄位驗證 )
系列文
用 Sanity 跟 Nextjs 重寫個人部落格30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言