自定义字段
¥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.
配置
¥Configuration
可以在 市场 上找到现成的自定义字段。安装这些插件后,无需其他配置,即可开始使用(参见 usage)。
¥Ready-made custom fields can be found on the Marketplace. Once installed these, no other configuration is required, and you can start using them (see usage).
你也可以开发自己的自定义字段。
¥You can also develop your own custom field.
开发你自己的自定义字段
¥Developing your own custom field
虽然添加自定义字段的推荐方法是通过创建插件,但特定于应用的自定义字段也可以在 src/index
和 src/admin/app
文件中找到的全局 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
and src/admin/app
files.
-
自定义字段只能使用插件在 Marketplace 上共享和分发。
¥Custom fields can only be shared and distributed on the Marketplace using plugins.
-
自定义字段无法向 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.
通过插件注册自定义字段需要创建并启用插件(参见 插件开发)。
¥Registering a custom field through a plugin requires creating and enabling a plugin (see Plugins development).
自定义字段插件包括服务器和管理面板部分。自定义字段必须先在两个部分中注册,然后才能在 Strapi 的管理面板中使用。
¥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.
在服务器上注册自定义字段
¥Registering a custom field on the server
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 some parameters.
Parameters available to register the custom field on the server:
范围 | 描述 | 类型 |
---|---|---|
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 |
示例:在服务器上注册示例 "color" 自定义字段:
¥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):
- JavaScript
- TypeScript
module.exports = ({ strapi }) => {
strapi.customFields.register({
name: "color",
plugin: "color-picker",
type: "string",
inputSize: {
// optional
default: 4,
isResizable: true,
},
});
};
export default ({ strapi }: { strapi: any }) => {
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:
- JavaScript
- TypeScript
module.exports = {
register({ strapi }) {
strapi.customFields.register({
name: "color",
plugin: "color-picker",
type: "text",
inputSize: {
// optional
default: 4,
isResizable: true,
},
});
},
};
export default {
register({ strapi }: { strapi: any }) {
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 some parameters.
Parameters available to register the custom field on the server:
范围 | 描述 | 类型 |
---|---|---|
name | 自定义字段的名称 | String |
pluginId (可选) | 创建自定义字段的插件名称 ❗️ 如果定义,则服务器注册上的 plugin 值必须具有相同的值(参见 在服务器上注册自定义字段) | String |
type | 自定义字段将使用的现有 Strapi 数据类型 ❗️ 不能使用关系、媒体、组件或动态区域。 | String |
icon (可选) | 自定义字段的图标 | React.ComponentType |
intlLabel | 名字的翻译 | |
intlDescription | 描述的翻译 | |
components | 在内容管理器中显示自定义字段所需的组件(参见 components) | |
options (可选) | 内容类型生成器使用的选项(参见 options) | Object |
示例:在管理面板中注册示例 "color" 自定义字段:
¥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):
- JavaScript
- TypeScript
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('./components/Input').then((module) => ({
default: module.Input,
})),
},
options: {
// declare options here
},
});
},
// ... bootstrap() goes here
};
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('./components/Input').then((module) => ({
default: module.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):
- JavaScript
- TypeScript
export default {
register(app) {
app.customFields.register({
// …
components: {
Input: async () =>
import('./components/Input').then((module) => ({
default: module.Input,
})),
},
// …
});
},
};
export default {
register(app) {
app.customFields.register({
// …
components: {
Input: async () =>
import('./components/Input').then((module) => ({
default: module.Input,
})),
},
// …
});
},
};
Props passed to the custom field Input
component:
属性 | 描述 | 类型 |
---|---|---|
attribute | 具有自定义字段的基础 Strapi 类型和选项的属性对象 | { type: String, customField: String } |
description | 配置视图 中设置的字段描述 | |
placeholder | 配置视图 中设置的字段占位符 | |
hint | 配置视图 中设置的字段描述以及最小/最大 验证要求 | String |
name | 内容类型构建器中设置的字段名称 | String |
intlLabel | 在内容类型构建器或配置视图中设置的字段名称 | |
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 | 验证后收到错误 | |
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.
- JavaScript
- TypeScript
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;
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:
Parameters passed to the custom field options
object:
选项参数 | 描述 | 类型 |
---|---|---|
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:
-
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 | 输入标签的翻译 | |
type | 输入的类型(例如,select 、checkbox ) | String |
示例:声明示例 "color" 自定义字段的选项:
¥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):
- JavaScript
- TypeScript
// 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",
}),
}),
},
});
},
};
// 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.
用法
¥Usage
在管理面板中
¥In the admin panel
你可以通过从 市场 安装自定义字段或创建自己的字段来将自定义字段添加到 Strapi。
¥Custom fields can be added to Strapi either by installing them from the Marketplace or by creating your own.
自定义字段添加到 Strapi 后,即可添加到任何内容类型。在为内容类型选择字段时,自定义字段会在“自定义”选项卡中列出。
¥Once added to Strapi, custom fields can be added to any content type. Custom fields are listed in the Custom tab when selecting a field for a content-type.
每个自定义字段类型都可以有基本和高级设置。市场 列出了可用的自定义字段,并为每个自定义字段提供专用文档,包括特定设置。
¥Each custom field type can have basic and advanced settings. The Marketplace lists available custom fields, and hosts dedicated documentation for each custom field, including specific settings.
在代码中
¥In the code
创建和使用后,自定义字段的定义就像模型架构中的任何其他属性一样。
¥Once created and used, custom fields are defined like any other attribute in the model's schema.
自定义字段在带有 type: customField
的模型的 attributes 中显式定义。
¥Custom fields are explicitly defined in the attributes of a model with type: customField
.
与其他类型的模型定义方式相比,自定义字段的属性还具有以下特性:
¥As compared to how other types of models are defined, custom fields' attributes also show the following specificities:
-
自定义字段具有
customField
属性。它的值作为唯一标识符,用于指示应使用哪个已注册的自定义字段,并遵循以下两种格式之一:¥Custom field have a
customField
attribute. Its value acts as a unique identifier to indicate which registered custom field should be used, and follows one of these 2 formats:格式 起源 plugin::plugin-name.field-name
自定义字段是通过插件创建的。 global::field-name
自定义字段特定于当前 Strapi 应用,并直接在 register
function 中创建。 -
自定义字段可以包含其他参数,具体取决于注册自定义字段时定义的内容(参见 服务器注册 和 管理面板注册)。
¥Custom fields can have additional parameters depending on what has been defined when registering the custom field (see server registration and admin panel registration).
示例:一个简单的 color
自定义字段模型定义:
¥Example: A simple color
custom field model definition:
{
// …
"attributes": {
"color": { // name of the custom field defined in the Content-Type Builder
"type": "customField",
"customField": "plugin::color-picker.color",
"options": {
"format": "hex"
}
}
}
// …
}