🙌

Filament で新規カスタマイズページを作成する

2023/11/13に公開

この記事について

Filamentのカスタマイズ方法について検証してみた 部分カスタマイズ編

  • 上記記事の続きです
  • 今回はFilamentの新規カスタマイズページについて検証してみます

新規カスタマイズページを作成する

新規カスタマイズページに関しては、下記が大変参考になりました。
https://github.com/askdkc/filamentphp_howto/blob/main/sub/add-custom-page.md

公式のドキュメントはこちら
https://filamentphp.com/docs/2.x/admin/resources/custom-pages

新規作成する

流れとしては前記事の作業の流れと同様で、コマンドでファイルを生成し、中身を作っていくという感じです。
適当にOtherというページを作ってみます。
下記コマンドを実行します。

php artisan make:filament-page Other

コマンド実行後は、下記ファイルが生成されます。

  • src/app/Filament/Pages/Other.php
  • src/resources/views/filament/pages/other.blade.php

表示を確認してみます。
other.blade.phpを下記のようにしてみます。

src/resources/views/filament/pages/other.blade.php
<x-filament::page>
    <p style="color: #00ff00; font-size: 3rem; line-height: 1;">Other表示</p>
</x-filament::page>

カスタムページでは、前記事で紹介したgetHeaderWidgetsgetFooterWidgetsメソッドが使用できます。
getHeaderWidgetsを使って、前記事でCustomerページに表示したMstItemウィジェットをヘッダー部分に表示してみます。

src/app/Filament/Pages/Other.php
    protected function getHeaderWidgets(): array
    {
        return [MstItemOverview::class];
    }

表示を確認すると、下記のように表示されます。

Other.phpgetViewDataメソッドも使用できるので、これらも使ってカスタマイズしていく形になりそうです。

自動生成ページに新規カスタマイズページのリンクを作成する

Customerページ下にあるCustomersOtherページを新規に作成し、Customerページリンクを用意します。
下記コマンドを実行します。

php artisan make:filament-page CustomersOther --resource=CustomerResource --type=custom

コマンド実行後、下記ファイルが生成されます。

  • src/app/Filament/Resources/CustomerResource/Pages/CustomersOther.php
  • src/resources/views/filament/resources/customer-resource/pages/customers-other.blade.php

CustomerResource.phpgetPagesメソッドを下記のように編集します。

src/app/Filament/Resources/CustomerResource.php
    public static function getPages(): array
    {
        return [
            "index" => Pages\ListCustomers::route("/"),
            "create" => Pages\CreateCustomer::route("/create"),
+           "customers-other" => Pages\CustomersOther::route(
+               "/customers-other"
+           ),
            "edit" => Pages\EditCustomer::route("/{record}/edit"),
        ];
    }

ここはいわゆるルーティングの定義のようなものとなります。

一覧ページのテーブル内の右上にリンクを表示させます。
CustomerResource.phptableメソッドを下記のように編集します。

src/app/Filament/Resources/CustomerResource.php
    return $table
+       ->headerActions([
+           Tables\Actions\Action::make("カスタムOther")->url(
+               static::getUrl("customers-other")
+           ),
+       ])
        ->columns([
~省略~

こうするとテーブル右上にリンクが表示されます。

移動先のページは、用途にあわせて編集していきます。

また、テーブル内にユーザーデータごとのリンクを用意することも可能です。
編集リンクのとなりにPersonalというリンクを作成し、ボタンをクリックしたらユーザーごとのcustomer-personalページに移動できるようにしてみます。
下記コマンドを実行します。

php artisan make:filament-page CustomerPersonal --resource=CustomerResource --type=custom

コマンド実行後、下記ファイルが生成されます。

  • src/app/Filament/Resources/CustomerResource/Pages/CustomerPersonal.php
  • src/resources/views/filament/resources/customer-resource/pages/customer-personal.blade.php

CustomerResource.phpgetPagesメソッドを下記のように編集します。

src/app/Filament/Resources/CustomerResource.php
    public static function getPages(): array
    {
        return [
            "index" => Pages\ListCustomers::route("/"),
            "create" => Pages\CreateCustomer::route("/create"),
            "customers-other" => Pages\CustomersOther::route(
                "/customers-other"
            ),
+           "customers-personal" => Pages\CustomerPersonal::route(
+               "/{customerId}/customers-personal"
+           ),
            "edit" => Pages\EditCustomer::route("/{record}/edit"),
        ];
    }

テーブルの編集リンクの右となりにリンクを表示させます。
CustomerResource.phptableメソッドを下記のように編集します。

src/app/Filament/Resources/CustomerResource.php
    return $table
~省略~
        ->actions([
            Tables\Actions\EditAction::make(),
+           Tables\Actions\Action::make("personal")->url(function (
+               Customer $record
+           ) {
+               return static::getUrl("customers-personal", [
+                   "customerId" => $record->id,
+               ]);
+           }),
        ])
~省略~

これでリンク自体は作成できます。

試しに、移動先であるcustomer-personalページも少し加工します。

CustomerPersonal.phpを下記のように編集します。

src/app/Filament/Resources/CustomerResource/Pages/CustomerPersonal.php
+   public string $customerId;
    
+   public function mount(string $customerId): void
+   {
+       $this->customerId = $customerId;
+   }

引数の$customerIdには、リンクで定義したCustomer.idが入っています。
mountメソッドは、Livewireのライフサイクルメソッドの1つで、コンポーネントが呼び出された初回だけ実行されます。

次に、customer-personal.blade.phpを下記を追加します。

src/resources/views/filament/resources/customer-resource/pages/customer-personal.blade.php
<x-filament::page>
+   <p>customer-personal {{$customerId}}</p>
</x-filament::page>

試しにページに移動してみると、下記のようにユーザーごとのページが表示されます。

その他

テーブルの列名を加工したい

テーブルの列名などで文字色を変えたり、文字を大きくしたりしたい場合は、labelメソッドを下記のようにすると加工できます。

src/app/Filament/Resources/CustomerResource.php
    Tables\Columns\TextColumn::make("mst_item_id")->label(
        function () {
            // 文字色をピンクにする
            return new HtmlString(
                "<b style='color: #ff69b4; initial-letter: normal'>マスタアイテムid</b>"
            );
        }
    ),


これはlavelメソッドだけでなく、descriptionメソッドなど引数にHtmlableが指定可能なメソッドなら可能そうです。

結合したカラムの検索

Customerページで表示している顧客情報の「名前」部分については、tableメソッドで下記のようにしています。

src/app/Filament/Resources/CustomerResource.php
    Tables\Columns\TextColumn::make("name")
        ->label("名前")
        ->sortable()
        ->getStateUsing(function (Customer $record): string {
            return $record->name_sei . $record->name_mei;
        })
        ->searchable(
            condition: ["name_sei", "name_mei"],
            isIndividual: true,
            isGlobal: false
        ),

姓と名を連結して表示し、「名前」列に対して検索が実行できるようにしています。
ただ、これだと姓/名それぞれのワードで検索するとヒットしますが、姓+名のワードで検索するとヒットしないという問題がありました。
(「山田大」と入力すると、「レコードが見つからない」という表示がされます)
これについて検証したところ、姓と名の間に半角スペースを入れるとヒットするようになります。

カラムを連結して表示している場合は、テーブルのカラムにあわせて単語を半角スペースで区切ると検索がしやすくなるかもしれません。

まとめ

部分カスタマイズでも述べましたが、いろいろ検証して感じたのは、Livewireの知見があるかないかでFilamentの難易度は変わるなと思いました。

基本自動生成で作成する機能はCRUD機能のみとし、少しでも特殊な用途となる画面についてはカスタマイズページとして作成する方が実装しやすいかなと思います。

業務でFilamentを使用する場合は、事前にチームのエンジニアや実際の管理画面を運用していく方たちの話を聞いて、どういったことを実現したいかと工数感を擦りあわせて、採用するか検討していければいいなと思いました。

参考

https://github.com/askdkc/filamentphp_howto
https://qiita.com/sgrs38/items/b4834954b20ccfbf88e9

EGSTOCK,Inc.

Discussion