自定义字段 Custom fields

了解如何使用自定义字段来扩展 Strapi 的内容类型功能。

自定义字段通过向内容类型和组件添加新类型的字段来扩展 Strapi 的功能。一旦通过插件创建或添加到 Strapi,自定义字段就可以像内置字段一样在内容类型构建器和内容管理器中使用。

本文档适用于自定义字段创建者:它描述了开发人员必须使用哪些 API 和函数来创建新的自定义字段。用户指南 描述了如何从 Strapi 的管理面板添加和使用自定义字段。

建议您为自定义字段开发专用的 插件。自定义字段插件包括服务器和管理面板部分。自定义字段必须在两个部分中注册,然后才能在 Strapi 的管理面板中使用。

一旦创建并使用,自定义字段的定义就像模型架构中的任何其他属性一样。使用自定义字段的属性的类型将表示为 customField(即 type: 'customField')。根据所使用的自定义字段,属性定义中可能存在一些其他属性 请参阅 模型文档

  • 虽然添加自定义字段的推荐方法是通过创建插件,但特定于应用程序的自定义字段也可以在 src/index.jssrc/admin/app/js 文件中的全局 register 函数 中注册。
  • 自定义字段只能使用插件共享。

在服务器上注册自定义字段

通过插件注册自定义字段需要创建和启用插件(请参阅 插件开发)。

Strapi 的服务器需要了解所有自定义字段,以确保使用自定义字段的属性有效。

strapi.customFields 对象在 Strapi 实例上公开一个 register() 方法。此方法用于在插件的服务器 注册生命周期 期间在服务器上注册自定义字段。

strapi.customFields.register() 通过传递具有以下参数的对象(或对象数组)在服务器上注册一个或多个自定义字段:

参数描述类型
name自定义字段的名称String
plugin
(可选)
创建自定义字段的插件的名称
❗️ 如果已定义,管理面板注册上的 pluginId 值必须具有相同的值 请参阅在管理面板中注册自定义字段
String
type自定义字段将使用的数据类型String
inputSize
(可选)
用于定义管理面板中自定义字段输入宽度的参数Object

可选的 inputSize 对象(指定时)必须包含以下所有参数:

参数描述类型
default输入字段在管理面板的 12 列网格中占据的默认列大小。
该值可以是 46812
Integer
isResizable是否可以调整输入的大小Boolean
当前限制

当前:

  • 自定义字段无法向 Strapi 添加新数据类型,必须使用 模型属性 文档中描述的现有内置 Strapi 数据类型。
  • 您也无法修改现有数据类型。
  • Strapi 独有的特殊数据类型(例如关系、媒体、组件或动态区域数据类型)不能用于自定义字段。

示例:在服务器上注册示例“颜色”自定义字段:

在以下示例中,使用 CLI 生成器创建了 color-picker 插件(请参阅 插件开发):

./src/plugins/color-picker/server/register.js
js
'use strict'

module.exports = ({ strapi }) => {
  strapi.customFields.register({
    name: 'color',
    plugin: 'color-picker',
    type: 'string',
    inputSize: {
      // optional
      default: 4,
      isResizable: true,
    },
  })
}

如果您没有由 CLI 生成器搭建的插件代码,也可以直接在 strapi-server.js 文件中声明自定义字段:

./src/plugins/color-picker/strapi-server.js
js
module.exports = {
  register({ strapi }) {
    strapi.customFields.register({
      name: 'color',
      plugin: 'color-picker',
      type: 'text',
      inputSize: {
        // optional
        default: 4,
        isResizable: true,
      },
    })
  },
}

Registering a custom field in the admin panel

通过插件注册自定义字段需要创建并启用插件(参见插件开发)

自定义字段必须在 Strapi 的管理面板中注册,才能在内容类型构建器和内容管理器中使用。

app.customFields 对象在 StrapiApp 实例上公开 register() 方法。此方法用于在插件的管理 注册生命周期 期间在管理面板中注册自定义字段。

app.customFields.register() 通过传递具有以下参数的对象(或对象数组)在管理面板中注册一个或多个自定义字段:

参数描述类型
name自定义字段的名称String
pluginId

可选
创建自定义字段的插件的名称

❗️ 如果已定义,服务器注册上的 plugin 值必须具有相同的值(请参阅在服务器上注册自定义字段)
String
type自定义字段将使用的现有 Strapi 数据类型

❗️ 不能使用关系、媒体、组件或动态区域。
String
icon

可选
自定义字段的图标React.ComponentType
intlLabel名称的翻译IntlObject
intlDescription描述的翻译IntlObject
components在内容管理器中显示自定义字段所需的组件(请参阅组件)
options

可选
内容类型构建器要使用的选项(请参阅选项)Object

示例:在管理面板中注册示例“颜色”自定义字段:

在以下示例中,使用 CLI 生成器创建了 color-picker 插件(请参阅 插件开发):

./src/plugins/color-picker/admin/src/index.js
jsx
import ColorPickerIcon from './components/ColorPicker/ColorPickerIcon'

export default {
  register(app) {
    // ... app.addMenuLink() 放在此处
    // ... app.registerPlugin() 放在此处

    app.customFields.register({
      name: 'color',
      pluginId: 'color-picker', // 自定义字段由颜色选择器插件创建
      type: 'string', // 颜色将存储为字符串
      intlLabel: {
        id: 'color-picker.color.label',
        defaultMessage: 'Color',
      },
      intlDescription: {
        id: 'color-picker.color.description',
        defaultMessage: 'Select any color',
      },
      icon: ColorPickerIcon, // 不要忘记创建/导入图标组件
      components: {
        Input: async () =>
          import(
            /* webpackChunkName: "input-component" */ './components/Input'
          ),
      },
      options: {
        // 在此处声明选项
      },
    })
  },
  // ... bootstrap() goes here
}

Components

app.customFields.register() 必须传递一个带有 Input React 组件的 components 对象,以便在内容管理器的编辑视图中使用。

示例:注册输入组件

在以下示例中,使用 CLI 生成器创建了 color-picker 插件(请参阅 插件开发):

./src/plugins/color-picker/admin/src/index.js
jsx
export default {
  register(app) {
    app.customFields.register({
      // …
      components: {
        Input: async () =>
          import(/* webpackChunkName: "input-component" */ './Input'),
      },
      // …
    })
  },
}

自定义字段输入组件接收以下 props:

Prop描述类型
attribute具有自定义字段的底层 Strapi 类型和选项的属性对象{ type: String, customField: String }
description配置视图 中设置的字段描述IntlObject
placeholder配置视图 中设置的字段占位符IntlObject
hint配置视图中设置的字段描述以及最小/最大验证要求String
name在内容类型构建器中设置的字段名称String
intlLabel在内容类型构建器中设置的字段名称或配置视图IntlObject
onChange输入更改事件的处理程序。name 参数引用字段名称。type 参数引用底层 Strapi 类型({ target: { name: String value: unknown type: String } }) => void
contentTypeUID字段所属的内容类型String
type自定义字段 uid,例如 plugin::color-picker.colorString
value底层 Strapi 类型期望的输入值unknown
required该字段是否为必填项boolean
error验证后收到的错误IntlObject
disabled输入是否被禁用boolean

从 Strapi v4.13.0 开始,内容管理器中的字段可以通过 URLSearchParam field 自动聚焦。建议将输入组件包装在 React 的 forwardRef 方法中;您应该将相应的 ref 传递给 input 元素。

示例:自定义文本输入

在下面的示例中,我们提供了一个受控的自定义文本输入。所有输入都应受控,否则其数据将不会在保存时提交。

./src/plugins/<plugin-name>/admin/src/components/Input.js
jsx
import * as React from 'react'

import { useIntl } from 'react-intl'

const Input = React.forwardRef((props, ref) => {
  const { attribute, disabled, intlLabel, name, onChange, required, value }
    = props // these are just some of the props passed by the content-manager

  const { formatMessage } = useIntl()

  const handleChange = (e) => {
    onChange({
      target: { name, type: attribute.type, value: e.currentTarget.value },
    })
  }

  return (
    <label>
      {formatMessage(intlLabel)}
      <input
        ref={ref}
        name={name}
        disabled={disabled}
        value={value}
        required={required}
        onChange={handleChange}
      />
    </label>
  )
})

export default Input

有关提供给 customFields 的 props 的更详细视图及其使用方法,请查看 Strapi 代码库中的 ColorPickerInput 文件

选项

app.customFields.register() 可以传递具有以下参数的附加 options 对象:

选项参数说明类型
base内容类型构建器中字段的 Base settings 选项卡中可用的设置ObjectArray of Objects
advanced内容类型构建器中字段的 Advanced settings 选项卡中可用的设置对象对象数组
验证器返回对象的验证器函数,用于清理输入。使用 yup 架构对象函数

基本高级 设置均接受对象或对象数组,每个对象都是一个设置部分。每个设置部分可以包括:

  • sectionTitle 以将部分标题声明为 IntlObject
  • 以及作为对象数组的 items 列表。

items 数组中的每个对象可以包含以下参数:

项目参数描述类型
name输入的标签。
必须使用 options.settingName 格式。
String
description在内容类型构建器中使用的输入的描述IntlObject
intlLabel输入标签的翻译IntlObject
type输入的类型(例如,selectcheckboxString

示例:声明示例“颜色”自定义字段的选项:

在以下示例中,使用 CLI 生成器创建了 color-picker 插件(请参阅 插件开发):

./src/plugins/color-picker/admin/src/index.js
jsx
// imports go here (ColorPickerIcon, pluginId, yup package…)

export default {
  register(app) {
    // ... app.addMenuLink() goes here
    // ... app.registerPlugin() goes here
    app.customFields.register({
      // …
      options: {
        base: [
          /*
           声明要添加到内容类型构建器中字段的“基本设置”部分的设置
          */
          {
            sectionTitle: {
              // 添加“格式”设置部分
              id: 'color-picker.color.section.format',
              defaultMessage: 'Format',
            },
            items: [
              // 向该部分添加设置项
              {
                /*
                  添加“颜色格式”下拉菜单,在两种不同的颜色值格式选项之间进行选择:十六进制或 RGBA
                */
                intlLabel: {
                  id: 'color-picker.color.format.label',
                  defaultMessage: 'Color format',
                },
                name: 'options.format',
                type: 'select',
                value: 'hex', // 默认选中的选项
                options: [
                  // 列出所有可用的“颜色格式”选项
                  {
                    key: 'hex',
                    defaultValue: 'hex',
                    value: 'hex',
                    metadatas: {
                      intlLabel: {
                        id: 'color-picker.color.format.hex',
                        defaultMessage: 'Hexadecimal',
                      },
                    },
                  },
                  {
                    key: 'rgba',
                    value: 'rgba',
                    metadatas: {
                      intlLabel: {
                        id: 'color-picker.color.format.rgba',
                        defaultMessage: 'RGBA',
                      },
                    },
                  },
                ],
              },
            ],
          },
        ],
        advanced: [
          /*
           声明要添加到内容类型构建器中字段的“高级设置”部分的设置
          */
        ],
        validator: args => ({
          format: yup.string().required({
            id: 'options.color-picker.format.error',
            defaultMessage: 'The color format is required',
          }),
        }),
      },
    })
  },
}

Strapi 代码库提供了如何描述设置对象的示例:检查 baseForm.ts 文件中的 base 设置和 advancedForm.js 文件中的 advanced 设置。基本表单以内联方式列出设置项,但高级表单从 attributeOptions.js 文件中获取设置项。