EntityFormを「カスタマイズしたい。」「増やしたい。」って時、ありますよね。
え、いまいちイメージつかないですか?
今回は、Core搭載のFormModeを利用してCustomのControllerでFormを実装してみましょう。
どういうシチュエーション...?
よくあるのってこんな感じですよね。
- 表示設定(ダークモード、言語設定)
- アカウント設定(メール、ユーザー名、住所)
- プロファイル(趣味やカジュアルな設定項目)
- API連携(外部連携用のAPITokenを入力できるフォーム)
- アカウント登録
- パスワード設定
「ユーザー設定だけでも複数画面を用意したい」って要件、よくあるんじゃないでしょうか。
今回は、Drupalでそれを実装してみましょう。
各エンティティが持つフォームって、標準インストールでは1つしか使えないはずです。(※ UserEntityの場合は、登録フォームがありますよね)
大丈夫。魔改造はしません。全部 DrupalCoreのAPI に沿った方法で実装します。
材料はこちら。
1. FormMode
フォームモード使ってますか?
InlineEnitityFormと相性ばっちしですので、あまりコードをかかないタイプのサイトビルダーの方には馴染みあるのでは...?
2. FormAPI
標準のFormAPIを利用します。実装したことないって人も大丈夫。
今回は、CoreのUserForm(ProfileForm)をほんの少し拡張するだけ。
3. Controller
Routingを定義して、簡単にページを作るには手っ取り早いですよね。
DrupalでのControllerの実装については、別記事で紹介していますのでそちらもぜひ。(まだ書けてません。しばしお待ちを。)
なんと今回は3つの機能のみで実装可能です。
実装方法
1. FormModeの定義
まずはGUIでFormModeを作成してください。
マシンネームメモっててくださいね。
2. Formの実装
/**
* カスタムユーザーフォームクラス: API設定 フォーム.
*/
class ProfileApiForm extends ProfileForm {
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state, ?UserInterface $entity = NULL) {
// 親クラスの buildForm を呼び出す.
$form = parent::buildForm($form, $form_state);
// ここで親のフォームを呼び出したあとにいろいろカスタマイズが可能です.
$form['#id'] = 'user_api_form';
return $form;
}
}
3. 設定したFormをEntityFormとして登録
手順: 1 でメモしたマシンネームをこちらで使います。
/**
* Implements hook_entity_type_build().
*/
function hook_entity_type_build(array &$entity_types) {
if (isset($entity_types['user'])) {
$entity_types['user']->setFormClass('profile_default', ProfileDefaultForm::class);
$entity_types['user']->setFormClass('profile_display', ProfileDisplayForm::class);
$entity_types['user']->setFormClass('profile_api', ProfileApiForm::class);
}
}
3. ControllerとRoutingの実装
割愛します。
Controllerの実装はまた別の記事で書きますね。
4. Controller内でFormを構築
DrupalのControllerBaseには、EntityFormBuilderを利用できるよう組み込みされています。
getForm メソッドで、Formを生成しましょう。
class ProfileApiForm extends ControllerBase {
public function __invoke(): array {
// フォームの生成.
$form = $this->entityFormBuilder()->getForm($user, 'profile_api');
return [
'#form' => $form,
];
}
}
5. 動作確認
あとは表示確認してみましょう。
まとめ
今回は、ControllerでEntityFormを呼び出す方法について紹介しました。
1からFormを実装してますので。
hook_form_alter() なんて不要...。
EventSubscriber なんて不要...。
ですよね!
参考
このあたりはドキュメントが少ないので難しいですよね...。