You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Sanity.io中构建含子主题的课程嵌套Schema?

问题描述

我想要搭建一个视频讲师网站,需要在Sanity.io中创建课程的嵌套Schema,要求课程包含主题,每个子主题需具备子主题名称、时长、视频URL属性。目前我不清楚如何实现该Schema,以下是我的示例代码,希望获得帮助或找到同类参考Schema:

export default {
  name: "Courses",
  title: "Property",
  type: "document",
  fields: [
    {
      title: "Movie",
      name: "movie",
      type: "document",
      fields: [
        {
          title: "Title",
          name: "title",
          type: "string",
        },
        {
          title: "Poster",
          name: "poster",
          type: "image",
        },
        {
          title: "Sub-Topic",
          name: "directors",
          type: "array",
          of: [{ type: "string" }],
        },
        {
          title: "Video URL",
          name: "imageUrl",
          type: "url",
        },
        {
          title: "Rich text example",
          name: "myRichTextExample",
          type: "array",
          of: [{ type: "block" }],
        },
      ],
    },
修正后的Schema示例

下面是完全符合需求的Sanity Schema,解决了嵌套结构问题,同时优化了字段语义化和实用性:

export default {
  name: "course",
  title: "课程",
  type: "document",
  fields: [
    {
      title: "课程标题",
      name: "courseTitle",
      type: "string",
      description: "填写课程的主标题"
    },
    {
      title: "课程海报",
      name: "coursePoster",
      type: "image",
      options: {
        hotspot: true // 支持图片裁剪定位
      }
    },
    {
      title: "课程子主题列表",
      name: "courseSubTopics",
      type: "array",
      of: [
        {
          type: "object",
          name: "subTopic",
          title: "子主题",
          fields: [
            {
              title: "子主题名称",
              name: "topicName",
              type: "string",
              validation: Rule => Rule.required() // 必填字段
            },
            {
              title: "时长(分钟)",
              name: "duration",
              type: "number",
              description: "填写视频的时长,单位为分钟",
              validation: Rule => Rule.min(0.1).required() // 限制最小时长并必填
            },
            {
              title: "视频URL",
              name: "videoUrl",
              type: "url",
              validation: Rule => Rule.uri({ scheme: ['http', 'https', 'youtube', 'vimeo'] }).required() // 限制合法协议并必填
            },
            {
              title: "主题简介",
              name: "topicDescription",
              type: "array",
              of: [{ type: "block" }]
            }
          ],
          preview: {
            select: {
              title: "topicName",
              subtitle: "duration"
            },
            prepare(selection) {
              const { title, subtitle } = selection;
              return {
                title: title,
                subtitle: `${subtitle} 分钟`
              };
            }
          }
        }
      ]
    },
    {
      title: "课程总简介",
      name: "courseDescription",
      type: "array",
      of: [{ type: "block" }]
    }
  ]
}
核心实现要点
  • 嵌套结构实现:用object类型定义单个子主题的字段集合,再通过array类型的of属性,让课程可以包含多个子主题
  • 必填验证:给关键字段(子主题名称、时长、视频URL)添加必填规则,避免缺失信息
  • 编辑体验优化:配置preview属性,在Sanity Studio的文档列表中直接显示子主题的名称和时长,不用点进去查看
  • URL合法性校验:限制视频URL的协议类型,确保输入的链接是有效的视频地址
原示例的问题修正
  • 原示例中在fields里嵌套type: "document"是错误的,Sanity的文档类型不能嵌套,嵌套结构必须用object类型
  • 字段名与功能不匹配(比如directors对应子主题、imageUrl对应视频URL),已修正为语义化命名,便于后续开发维护
  • 补充了时长字段的类型和验证逻辑,完善了必填规则

内容的提问来源于stack exchange,提问作者abhishek sahu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 19:27:31