自定义字段
¥Custom fields
自定义字段通过向内容类型和组件添加新类型的字段来扩展 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).
虽然添加自定义字段的推荐方法是通过创建插件,但特定于应用的自定义字段也可以在
src/index.js
和src/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 insrc/index.js
andsrc/admin/app/js
files.自定义字段只能使用插件共享。
¥Custom fields can only be shared using plugins.
在服务器上注册自定义字段
¥Registering a custom field on the server
通过插件注册自定义字段需要创建并启用插件(参见 插件开发)。
¥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 列网格中占据的默认列大小。 该值可以是 4 、6 、8 或 12 。 | 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):
"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:
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
通过插件注册自定义字段需要创建并启用插件(参见 插件开发)。
¥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 (可选) | 内容类型生成器使用的选项(参见 options) | Object |
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):
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):
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.color | String |
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.
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 | 内容类型生成器字段的基本设置选项卡中提供的设置 | Object 或 Array of Objects |
advanced | 内容类型生成器字段的高级设置选项卡中提供的设置 | Object 或 Array of Objects |
validator | 验证器函数返回一个对象,用于清理输入。使用 yup 架构对象。 | Function |
base
和 advanced
设置都接受一个对象或对象数组,每个对象都是一个设置部分。每个设置部分可以包括:
¥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 anIntlObject
以及作为对象数组的
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 | 输入的类型(例如,select 、checkbox ) | String |
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):
// 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.