カスタムフィールド(Custom Fields)
Page summary:
カスタムフィールドは、コンテンツタイプビルダーとコンテンツマネージャーでネイティブフィールドと同様に振る舞う新しいフィールド型を Strapi に足します。このページではプラグインでの導入・自作と、プログラムからの登録方法を説明します。
カスタムフィールドは、コンテンツタイプやコンポーネントに新しい種類のフィールドを足して Strapi を拡張します。プラグインで作成・追加したあとは、コンテンツタイプビルダーとコンテンツマネージャーで組み込みフィールドと同様に利用できます。
設定
用意されたカスタムフィールドは Marketplace から入手できます。インストール後は追加設定なしで使い始められます(使い方 も参照)。
独自のカスタムフィールドを開発することもできます。
独自のカスタムフィールドを開発する
推奨はプラグインで足す方法ですが、 アプリ専用のカスタムフィールドは、src/index および src/admin/app のグローバル register 関数 内に登録することもできます。
- カスタムフィールドをマーケットプレースで共有・配布できるのはプラグイン経由のみです。
- Strapi に新しいデータ型を足すことはできず、モデルの属性 にある既存の組み込み型だけを使えます。
- 既存のデータ型を変更することはできません。
- relation、media、component、dynamic zone など Strapi 特有の型は、カスタムフィールドでは使えません。
プラグイン経由でカスタムフィールドを登録するには、プラグインを作成して有効にする必要があります(プラグイン開発 を参照)。
カスタムフィールドのプラグインはサーバー側と管理パネル側の両方を含みます。Strapi の管理パネルで使うには、両方に登録する必要があります。
サーバーでのカスタムフィールドの登録
カスタムフィールドを 使った属性が正しいことを確認するため、Strapi サーバーはすべてのカスタムフィールドを把握している必要があります。
Strapi インスタンスの strapi.customFields オブジェクトは register() メソッドを公開しています。プラグインのサーバー register ライフサイクル でサーバーにカスタムフィールドを登録するときに使います。
strapi.customFields.register() は、オブジェクト(またはオブジェクトの配列)を渡して、サーバーに1つまたは複数のカスタムフィールドを登録します。
サーバーでカスタムフィールドを登録するときに使えるパラメーター
| パラメーター | 説明 | 型 |
|---|---|---|
name | カスタムフィールドの名前 | String |
plugin(任意) | カスタムフィールドを提供するプラグインの名前 ❗️ 指定する場合、管理パネル側登録の pluginId と同じ値にしてください(管理パネルでのカスタムフィールドの登録 を参照) | String |
type | カスタムフィールドが使うデータ型 | String |
inputSize(任意) | 管理パネルでのカスタムフィールド入力の幅を定義するパラメーター | Object |
inputSize を指定する場合、次のパラメーターをすべて含める必要があります。
| パラメーター | 説明 | 型 |
|---|---|---|
default | 管理パネルの12列グリッドで入力が占める列数の既定値4、6、8、12 のいずれか | Integer |
isResizable | 入力のリサイズを許可するかどうか | Boolean |
例: サーバーに「color」カスタムフィールドを登録する
次の例では、CLI ジェネレーターで color-picker プラグインを作成した想定です(プラグイン開発 を参照)。
- 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 に直接宣言することもできます。
- 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,
},
});
},
};
管理パネルでのカスタムフィールドの登録
プラグイン経由でカスタムフィールドを登録するには、プラグインを作成して有効にする必要があります(プラグイン開発 を参照)。
コンテンツタイプビルダーとコンテンツマネージャーで使うには、Strapi の管理パネルにカスタムフィールドを登録する必要があります。
StrapiApp インスタンスの app.customFields オブジェクトは register() メソッドを公開しています。プラグインの管理画面 register ライフサイクル で管理パネルにカスタムフィールドを登録するときに使います。
app.customFields.register() は、オブジェクト(またはオブジェクトの配列)を渡して、管理パネルに1つまたは複数のカスタムフィールドを登録します。
管理パネルで カスタムフィールドを登録するときに使えるパラメーター
| パラメーター | 説明 | 型 |
|---|---|---|
name | カスタムフィールドの名前 | String |
pluginId(任意) | カスタムフィールドを提供するプラグインの名前 ❗️ 指定する場合、サーバー登録の plugin と同じ値にしてください(サーバーでのカスタムフィールドの登録 を参照) | String |
type | カスタムフィールドが使う既存の Strapi データ型 ❗️ relation、media、component、dynamic zone は使えません。 | String |
icon(任意) | カスタムフィールドのアイコン | React.ComponentType |
intlLabel | 表示名の翻訳 | IntlObject |
intlDescription | 説明文の翻訳 | IntlObject |
components | コンテンツマネージャーでカスタムフィールドを表示するために必要なコンポーネント(コンポーネント を参照) | |
options(任意) | コンテンツタイプビルダーで使うオプション(オプション を参照) | Object |
例: 管理パネルに「color」カスタムフィールドを登録する
次の例では、CLI ジェネレーターで color-picker プラグインを作成した想定です(プラグイン開発 を参照)。
- 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
};
コンポーネント
app.customFields.register() は、コンテンツマネージャーの編集ビューで使う Input React コンポーネントを含む components オブジェクトを渡す必要があります。
例: Input コンポーネントを登録する
次の例では、CLI ジェネレーターで color-picker プラグインを作成した想定です(プラグイン開発 を参照)。
- 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,
})),
},
// …
});
},
};
カスタムフィールドの 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 | フィールドが属するコンテンツタイプの UID | String |
type | カスタムフィールドの UID(例: plugin::color-picker.color) | String |
value | 基となった Strapi の型が期待する入力値 | unknown |
required | 必須フィールドかどうか | boolean |
error | バリデーション後に受け取ったエラー | IntlObject |
disabled | 入力が無効かどうか | boolean |
Strapi v4.13.0 以降、コンテンツマネージャーでは URL クエリの field でフィールドに自動フォーカスできます。入力コンポーネントは React の `forwardRef` でラップし、input 要素に対応する ref を渡すことを推奨します。
例: カスタムのテキスト入力
次の例では制御されたテキスト入力を示します。保存時に値を送るには、入力はすべて制御コンポーネントにしてください。
- 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 を参照してください。
オプション
app.customFields.register() には、次のパラメーターを持つ追加の options オブジェクトを渡せます。
カスタムフィールドの options オブジェクトのパラメーター
| オプションのパラメーター | 説明 | 型 |
|---|---|---|
base | コンテンツタイプビルダーで当該フィールドの「基本設定」タブに表示される設定 | 単一の Object または Object の配列 |
advanced | コンテンツタイプビルダーで当該フィールドの「高度な設定」タブに表示される設定 | 単一の Object または Object の配列 |
validator | 入力を 正規化するために使うオブジェクトを返すバリデーター関数。yup のスキーマオブジェクト を利用します | Function |
base と advanced は、それぞれ設定セクションを表すオブジェクト、またはその配列を受け取ります。各設定セクションには次を含められます。
- セクション見出しを宣言する
sectionTitle(IntlObject) - オブジェクトの配列である
items
items 配列の各オブジェクトに次のパラメーターを指定できます。
| items のパラメーター | 説明 | 型 |
|---|---|---|
name | 入力のラベル。options.settingName 形式である必要があります。 | String |
description | コンテンツタイプビルダーで使う入力の説明 | String |
intlLabel | 入力ラベルの翻訳 | `IntlObject` |
type | 入力の種類(例: select、checkbox) | String |
例: 「color」カスタムフィールドのオプションを宣言する
次の 例では、CLI ジェネレーターで color-picker プラグインを作成した想定です(プラグイン開発 を参照)。
- 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 コードベースにあります。base は `baseForm.ts`、advanced は `advancedForm.ts` を参照してください。基本設定フォームは項目をインラインで列挙し、高度な設定フォームの項目は `attributeOptions.js` から読み込みます。
使い方
管理パネルで
カスタムフィールドは、マーケットプレース からインストールするか、自作して Strapi に足せます。
Strapi に追加したあと、任意のコンテンツタイプにカスタムフィールドを追加できます。コンテンツタイプにフィールドを選ぶと、一覧は Custom タブに表示されます。
カスタムフィールドの型ごとに基本設定と高度な設定を持てます。Marketplace に利用可能なカスタムフィールドと、各フィ ールド専用の説明(設定を含む)があります。
コード上で
利用し始めたあと、カスタムフィールドはモデルのスキーマでは他の属性と同じように定義されます。
モデルの attributes で、type: customField として明示的に書きます。
ほかの型と比べ、カスタムフィールドの属性には次の点があります。
-
customField属性があります。値は登録済みのどのカスタムフィールドを使うかを示す一意の識別子で、次の2形式のいずれかです。形式 由来 plugin::plugin-name.field-nameプラグインで作成したカスタムフィールド global::field-name現在の Strapi アプリ専用で、 register関数 内に直接作成したカスタムフィールド -
登録時に定義した内容に応じて、カスタムフィールドには追加パラメーターを持てます(サーバーでの登録 と管理パネルでの登録 を参照)。
例: 単純な color カスタムフィールドのモデル定義
{
// …
"attributes": {
"color": { // name of the custom field defined in the Content-Type Builder
"type": "customField",
"customField": "plugin::color-picker.color",
"options": {
"format": "hex"
}
}
}
// …
}