iT邦幫忙

2024 iThome 鐵人賽

DAY 20
0

在繼續 Next.js 前端之前,先建立一個 網站設定 的資料型別作為網站的基本資料設定的後台,裡頭包含了 metadata 的設定、favicon、精選文章、每頁文章數量等等。


首先,在 schemaTypes 中建立一個新的檔案叫 website.ts

sanity-project
├── schemaTypes
│   ├── blogPost.tsx
│   ├── index.ts
│   └── website.ts // <- 新建立一個"網站設定"的資料型別
// ...

基礎設定:

// website.ts
import {defineType, defineField} from 'sanity'
import {getImageDimensions} from '@sanity/asset-utils'

export default defineType({
  name: 'website',
  title: '網站設定',
  type: 'document',
  fields: [],
})

設定完後再引入到 index.ts 中啟用它。

import website from './website'
import blogPost from './blogPost'

export const schemaTypes = [website, blogPost]

這樣就完成基本的設定了。


Sanity Schema Group

這次會用到之前都沒用到過的 group 來作為 schema 的分類。
用法是這樣:

// ...

export default defineType({
  name: 'website',
  title: '網站設定',
  type: 'document',
  groups: [
    {
      name: 'metadata',
      title: 'Metadata',
    },
    {
      name: 'mainContent',
      title: '顯示內容設定',
    },
  ],
  fields: [],
})

這樣就定義了兩個 group,接下來只要在要分進此群組的欄位定義加上 group 屬性,並且把 group name 寫入該欄位就完成了。

export default defineType({
  name: 'website',
  title: '網站設定',
  type: 'document',
  groups: [
    {
      name: 'metadata',
      title: 'Metadata',
    },
    {
      name: 'mainContent',
      title: '顯示內容設定',
    },
  ],
  fields: [
    defineField({
      name: 'metaTitle',
      title: 'Meta Title',
      type: 'string',
      group: 'metadata', // metadata group
      validation: (rule) => [
        rule.required().min(5).error('網站標題至少需要 5 個字'),
        rule.max(60).warning('網站標題長度不要超過 60 個字'),
      ],
    }),
    defineField({
      name: 'metaDescription',
      title: 'Meta Description',
      type: 'string',
      group: 'metadata', // metadata group
      validation: (rule) => rule.required(),
    }),
    // ...
    defineField({
      name: 'logo',
      title: '網站 Logo',
      type: 'image',
      group: 'mainContent', // mainContent group
      options: {
        accept: 'image/jpeg, image/png',
      },
      validation: (rule) => rule.required(),
    }),
  ],
})

這麼定義後在前端填資料的欄位就可以看到群組了。

https://ithelp.ithome.com.tw/upload/images/20241004/20101989lbTNiciUHW.jpg

並且選擇不同的群組就會有不同的資料群組資料了:

https://ithelp.ithome.com.tw/upload/images/20241004/20101989eaV0I0FHx3.jpg

https://ithelp.ithome.com.tw/upload/images/20241004/20101989Vp9tMFVvgj.jpg

最後,群組只是一個使用上的分類,並不會對實際產生的內容有任何影響,所以使不使用它其實也不是一定要。

Sanity reference Schema

在網站設定中有個比較特殊的欄位是精選文章,預期會在首頁上作為輪播的文章。
要時做出這樣的功能有不同的方法,可以是在個別文章中新增一個 boolean 型別的欄位,用那格 boolean 欄位來設定精選文章,或是在網頁設定用 reference 的方法來做參照。

defineField({
  name: 'featuredPosts',
  title: '精選文章',
  group: 'mainContent',
  type: 'array',
  of: [{type: 'reference', to: [{type: 'blogPost'}]}],
})

可以看到使用了 array ,並且裡面的元素是 referenceblogPost 型別。

https://ithelp.ithome.com.tw/upload/images/20241004/20101989VbnTUYVtfR.jpg

這樣就可以在 featuredPosts 欄位加入文章甚至直接新增文章了。


上一篇
Day 19 - Sanity GROQ Pagination
下一篇
Day 21 - Next.js 載入更多文章
系列文
用 Sanity 跟 Nextjs 重寫個人部落格30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言