Filament で部分カスタマイズページを作成する
この記事について
- Filamentで自動生成した画面に対して、カスタマイズ方法やカスタマイズページの作成方法がわからず、いろいろ調査してわかったことについて記載しました
- 同様にカスタマイズ方法に悩んでいる方の参考になれば幸いです
使用マシン/ツール
macOS Sonoma ver14.0
Docker Desktop ver4.23.0
Laravel Framework ver10.28.0
Filament ver2.17.53
環境構築
Filamentの環境構築については、下記記事で紹介してますのでご参考ください。
Filamentについて
Filament の構成は
- Tailwind
- Alpine.js
- Laravel
- Livewire
といった感じになっています。(頭文字をとってTALL stackと呼ぶらしいです)
個人的には、特にLivewireについてある程度理解しておくと、実装がしやすくなるかなと思います。
Livewireについては下記記事でも触れていますので、興味のある方はご参考ください。
※ 実装に動いているコードが見たい方はこちらから
https://github.com/eg-knakamura/study-filament
ひとえに カスタマイズ といっても
- 自動生成ページへの部分カスタマイズ
- 新規カスタマイズしたページを作成する
の2通りがあるのでそれぞれ掘り下げてみます
自動生成したページを部分カスタマイズする
ページを自動生成する
まずは検証用のページを自動生成機能を使って生成します。
流れは下記になります。
- 顧客情報を表示するページを自動生成で作成
- 顧客と紐づいている商品マスタデータをカスタマイズで表示する
下記コマンドでマイグレーションとモデルを作成します。
php artisan make:model -m Customer -- 顧客情報
php artisan make:model -m MstItem -- 商品マスタデータ
上記コマンドを実行すると、app/Models/
とdatabase/migrations/
にファイルが生成されます。
マイグレーションファイルをそれぞれ下記のように編集します。
public function up(): void
{
Schema::create("customers", function (Blueprint $table) {
$table->id();
$table->string("name_sei")->comment("名前(性)");
$table->string("name_mei")->comment("名前(名)");
$table->integer("mst_item_id")->comment("マスタアイテムID");
$table->timestamps();
});
\DB::table("customers")->insert([
0 => [
"id" => 1,
"name_sei" => "山田",
"name_mei" => "太郎",
"mst_item_id" => "1",
"created_at" => "2023-10-20 02:16:04",
"updated_at" => "2023-10-20 02:16:04",
],
[
"id" => 2,
"name_sei" => "山田",
"name_mei" => "大",
"mst_item_id" => "1",
"created_at" => "2023-10-20 02:16:04",
"updated_at" => "2023-10-20 02:16:04",
],
[
"id" => 3,
"name_sei" => "山田",
"name_mei" => "大吾",
"mst_item_id" => "1",
"created_at" => "2023-10-20 02:16:04",
"updated_at" => "2023-10-20 02:16:04",
],
[
"id" => 4,
"name_sei" => "山田",
"name_mei" => "大吾郎",
"mst_item_id" => "1",
"created_at" => "2023-10-20 02:16:04",
"updated_at" => "2023-10-20 02:16:04",
],
]);
}
Schema::create("mst_items", function (Blueprint $table) {
$table->id();
$table->string("name")->comment("アイテム名");
$table->timestamps();
});
\DB::table("mst_items")->insert([
0 => [
"id" => 1,
"name" => "アイテム1",
"created_at" => "2023-10-20 02:16:04",
"updated_at" => "2023-10-20 02:16:04",
],
]);
マイグレーション実行とモデルクラス編集後、下記コマンドで顧客ページのリソースクラスを生成します。
php artisan make:filament-resource Customer --generate
あとは、必要に応じて少し編集してみます。
今回は下記の画面のようにしてみました。
このページに対して、商品マスタデータを顧客テーブルの下に表示してみます。
部分カスタマイズする
公式ドキュメントの下記ページを参考にしています。
(実際はちょっと違うと思いますので、あくまでイメージです)
下記コマンドを実行します。
php artisan make:filament-widget MstItemOverview --resource=CustomerResource
実行後、下記ファイルが生成されます。
src/app/Filament/Resources/CustomerResource/Widgets/MstItemOverview.php
src/resources/views/filament/resources/customer-resource/widgets/mst-item-overview.blade.php
一旦この時点でMstItemを表示させてみたいと思います。
今回は一覧ページに表示させるので、src/app/Filament/Resources/CustomerResource/Pages/ListCustomers.php
を編集します。
(もし作成ページに表示させたい場合は/Pages/CreateCustomers.php
を、編集ページに表示させたい場合は/Pages/EditCustomers.php
を編集します)
+ protected function getHeaderWidgets(): array
+ {
+ return [
+ CustomerResource\Widgets\MstItemOverview::class
+ ];
+ }
+ protected function getFooterWidgets(): array
+ {
+ return [
+ CustomerResource\Widgets\MstItemOverview::class
+ ];
+ }
getHeaderWidgets
はページ上部に、getFooterWidgets
はページ下部に表示されます。
表示している内容をわかりやすくするためにmst-item-overview.blade.php
を編集します。
<x-filament::widget>
<x-filament::card>
- {{-- Widget content --}}
+ <p style="color: #ff0099; font-size: 1.125rem; line-height: 1.75rem;">MstItemウィジェット表示</p>
+ <table style="border-width: 2px; text-align: center">
+ <tr>
+ <th style="border-width: 2px; width: 150px">id</th><th style="border-width: 2px; width: 300px">商品名</th>
+ </tr>
+ <tr>
+ <td style="border-width: 2px; width: 150px">1</td><td style="border-width: 2px; width: 300px">test</td>
+ </tr>
+ </table>
</x-filament::card>
</x-filament::widget>
ここまで記述すると、顧客テーブルの上部と下部に表示されます。
表示は問題なさそうなので、実際にMstItemのデータを取得して表示してみます。
MstItemOverview.php
に下記メソッドを追加します。
public function getViewData(): array
{
$mstItems = MstItem::query()
->select("id", "name")
->get()
->toArray();
return [
"items" => $mstItems,
];
}
getViewData
メソッドは、テンプレート側に渡すデータを定義するメソッドです。
make:filament-widget
で生成したクラスはWidget
クラスを継承しており、Widget
クラスにはgetViewData
メソッドが定義されていて、これをオーバーライドしています。
他にも定義済みのメソッドがあるので、必要に応じてオーバーライドなど使用する形になると思います。
次に、mst-item-overview.blade.php
を下記のように変更します。
<table style="border-width: 2px; text-align: center">
<tr>
<th style="border-width: 2px; width: 150px">id</th><th style="border-width: 2px; width: 300px">商品名</th>
</tr>
- <tr>
- <td style="border-width: 2px; width: 150px">1</td><td style="border-width: 2px; width: 300px">test</td>
- </tr>
+ @foreach($items as $item)
+ <tr>
+ <td style="border-width: 2px; width: 150px">{{$item['id']}}</td><td style="border-width: 2px; width: 300px">{{$item['name']}}</td>
+ </tr>
+ @endforeach
</table>
これで実際にマスタデータを表示できました。
今回はテンプレート側も自作しましたが、コマンドの指定によってはテンプレートも自動生成されるようです。
今回は簡単なテーブル表示を作成しましたが、フォームの作成など用途に応じてカスタマイズすることは可能かなと思います。
フォーム用のコンポーネントを生成するコマンドや、テーブル用のコンポーネントを生成するコマンドなどが用意されているので、これを使ってカスタマイズしていく形になると思います。
ここまでの感想
- カスタマイズで生成したクラスはLivewireのコンポーネントとして扱う感じなので、Livewireの知見があるとFilamentは結構とっつきやすくなる印象がありました。
- 部分的にカスタマイズができるなら、Filamentを使っていくメリットは大きそうです。
- 次回は新規カスタマイズページについて検証してみたいと思います。
参考
Discussion