Skip to main content

自定义字段

¥Custom fields

🏗 正在进行的工作

此页面的内容可能尚未与 Strapi 5 完全同步。

¥The content of this page might not be fully up-to-date with Strapi 5 yet.

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

¥Custom fields extend Strapi’s capabilities by adding new types of fields to content-types and components. Once created or added to Strapi via plugins, custom fields can be used in the Content-Type Builder and Content Manager just like built-in fields.

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

¥The present documentation is intended for custom field creators: it describes which APIs and functions developers must use to create a new custom field. The User Guide describes how to add and use custom fields from Strapi's admin panel.

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

¥It is recommended that you develop a dedicated plugin for custom fields. Custom field plugins include both a server and admin panel part. The custom field must be registered in both parts before it is usable in Strapi's admin panel.

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

¥Once created and used, custom fields are defined like any other attribute in the model's schema. An attribute using a custom field will have its type represented as customField (i.e. type: 'customField'). Depending on the custom field being used a few additional properties may be present in the attribute's definition (see models documentation).

✏️ NOTES
  • 虽然添加自定义字段的推荐方法是通过创建插件,但特定于应用的自定义字段也可以在 src/index.jssrc/admin/app/js 文件中找到的全局 register function 中注册。

    ¥Though the recommended way to add a custom field is through creating a plugin, app-specific custom fields can also be registered within the global register function found in src/index.js and src/admin/app/js files.

  • 自定义字段只能使用插件共享。

    ¥Custom fields can only be shared using plugins.

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

¥Registering a custom field on the server

☑️ Prerequisites

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

¥Registering a custom field through a plugin requires creating and enabling a plugin (see Plugins development).

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

¥Strapi's server needs to be aware of all the custom fields to ensure that an attribute using a custom field is valid.

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

¥The strapi.customFields object exposes a register() method on the Strapi instance. This method is used to register custom fields on the server during the plugin's server register lifecycle.

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

¥strapi.customFields.register() registers one or several custom field(s) on the server by passing an object (or an array of objects) with the following parameters:

范围描述类型
name自定义字段的名称String
plugin

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

❗️ 如果定义,管理面板注册上的 pluginId 值必须具有相同的值(请参阅 在管理面板中注册自定义字段
String
type自定义字段将使用的数据类型String
inputSize

(可选)
用于定义管理面板中自定义字段输入宽度的参数Object

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

¥The optional inputSize object, when specified, must contain all of the following parameters:

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

当前:

¥Currently:

  • 自定义字段无法向 Strapi 添加新数据类型,必须使用 模型的属性 文档中描述的现有内置 Strapi 数据类型。

    ¥Custom fields cannot add new data types to Strapi and must use existing, built-in Strapi data types described in the models' attributes documentation.

  • 你也无法修改现有的数据类型。

    ¥You also cannot modify an existing data type.

  • Strapi 特有的特殊数据类型(例如关系、媒体、组件或动态区域数据类型)不能在自定义字段中使用。

    ¥Special data types unique to Strapi, such as relation, media, component, or dynamic zone data types, cannot be used in custom fields.

Example: Registering an example "color" custom field on the server:

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

¥In the following example, the color-picker plugin was created using the CLI generator (see plugins development):

./src/plugins/color-picker/server/register.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 文件中声明自定义字段:

¥The custom field could also be declared directly within the strapi-server.js file if you didn't have the plugin code scaffolded by the CLI generator:

./src/plugins/color-picker/strapi-server.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

☑️ Prerequisites

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

¥Registering a custom field through a plugin requires creating and enabling a plugin (see Plugins development).

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

¥Custom fields must be registered in Strapi's admin panel to be available in the Content-type Builder and the Content Manager.

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

¥The app.customFields object exposes a register() method on the StrapiApp instance. This method is used to register custom fields in the admin panel during the plugin's admin register lifecycle.

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

¥app.customFields.register() registers one or several custom field(s) in the admin panel by passing an object (or an array of objects) with the following parameters:

范围描述类型
name自定义字段的名称String
pluginId

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

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

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

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

(可选)
内容类型生成器使用的选项(参见 optionsObject
Example: Registering an example "color" custom field in the admin panel:

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

¥In the following example, the color-picker plugin was created using the CLI generator (see plugins development):

./src/plugins/color-picker/admin/src/index.js
import ColorPickerIcon from "./components/ColorPicker/ColorPickerIcon";

export default {
register(app) {
// ... app.addMenuLink() goes here
// ... app.registerPlugin() goes here

app.customFields.register({
name: "color",
pluginId: "color-picker", // the custom field is created by a color-picker plugin
type: "string", // the color will be stored as a string
intlLabel: {
id: "color-picker.color.label",
defaultMessage: "Color",
},
intlDescription: {
id: "color-picker.color.description",
defaultMessage: "Select any color",
},
icon: ColorPickerIcon, // don't forget to create/import your icon component
components: {
Input: async () =>
import(
/* webpackChunkName: "input-component" */ "./components/Input"
),
},
options: {
// declare options here
},
});
},

// ... bootstrap() goes here
};

组件

¥Components

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

¥app.customFields.register() must pass a components object with an Input React component to use in the Content Manager's edit view.

Example: Registering an Input component

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

¥In the following example, the color-picker plugin was created using the CLI generator (see plugins development):

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

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

¥Custom field input components receive the following props:

属性描述类型
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 元素。

¥As of Strapi v4.13.0, fields in the Content Manager can be auto-focussed via the URLSearchParam field. It's recommended that your input component is wrapped in React's forwardRef method; you should pass the corresponding ref to the input element.

Example: A custom text input

在以下示例中,我们提供受控的自定义文本输入。所有输入都应该受到控制,否则它们的数据将不会在保存时提交。

¥In the following example we're providing a custom text input that is controlled. All inputs should be controlled otherwise their data will not be submitted on save.

./src/plugins/<plugin-name>/admin/src/components/Input.js
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 文件

¥For a more detailed view of the props provided to the customFields and how they can be used check out the ColorPickerInput file in the Strapi codebase.

选项

¥Options

app.customFields.register() 可以传递一个附加的 options 对象,其参数如下:

¥app.customFields.register() can pass an additional options object with the following parameters:

选项参数描述类型
base内容类型生成器字段的基本设置选项卡中提供的设置ObjectArray of Objects
advanced内容类型生成器字段的高级设置选项卡中提供的设置ObjectArray of Objects
validator验证器函数返回一个对象,用于清理输入。使用 yup 架构对象Function

baseadvanced 设置都接受一个对象或对象数组,每个对象都是一个设置部分。每个设置部分可以包括:

¥Both base and advanced settings accept an object or an array of objects, each object being a settings section. Each settings section could include:

  • a sectionTitle 声明该部分的标题为 IntlObject

    ¥a sectionTitle to declare the title of the section as an IntlObject

  • 以及作为对象数组的 items 列表。

    ¥and a list of items as an array of objects.

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

¥Each object in the items array can contain the following parameters:

项目参数描述类型
name输入的标签。
必须使用 options.settingName 格式。
String
description内容类型生成器中使用的输入的描述String
intlLabel输入标签的翻译IntlObject
type输入的类型(例如,selectcheckboxString
Example: Declaring options for an example "color" custom field:

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

¥In the following example, the color-picker plugin was created using the CLI generator (see plugins development):

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

export default {
register(app) {
// ... app.addMenuLink() goes here
// ... app.registerPlugin() goes here
app.customFields.register({
// …
options: {
base: [
/*
Declare settings to be added to the "Base settings" section
of the field in the Content-Type Builder
*/
{
sectionTitle: {
// Add a "Format" settings section
id: "color-picker.color.section.format",
defaultMessage: "Format",
},
items: [
// Add settings items to the section
{
/*
Add a "Color format" dropdown
to choose between 2 different format options
for the color value: hexadecimal or RGBA
*/
intlLabel: {
id: "color-picker.color.format.label",
defaultMessage: "Color format",
},
name: "options.format",
type: "select",
value: "hex", // option selected by default
options: [
// List all available "Color format" 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: [
/*
Declare settings to be added to the "Advanced settings" section
of the field in the Content-Type Builder
*/
],
validator: (args) => ({
format: yup.string().required({
id: "options.color-picker.format.error",
defaultMessage: "The color format is required",
}),
}),
},
});
},
};
💡 提示

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

¥The Strapi codebase gives an example of how settings objects can be described: check the baseForm.ts file for the base settings and the advancedForm.ts file for the advanced settings. The base form lists the settings items inline but the advanced form gets the items from an attributeOptions.js file.