応援しているJリーグのサッカーチームが勝利した週末は嬉しいものですが、シーズンが終わりそうで寂しさも感じているこの頃。Hackerの皆様はいかかお過ごしでおられますでしょうか。

お休みはしっかり休んで、仕事はきっちりと能率的に行うものとしたいものですね。

概要

本連載は、Laravel+Filamentというフレームワーク&ライブラリの組み合わせを通じて、インストールから入りひとまず簡単に 開発環境で管理画面開発を短時間で始められることを目的にしています。


過去にNext.jsのCMS「Strapi」の記事も書いてありますのでよろしければご参考になさってください。


⇩第1回の記事は以下からご覧いただけます。

参考記事:

モルドスプーンアイコン

第2回の今回は基本的なブログの入稿・一覧画面構築を行えるところまでを解説します。

それではどうぞ最後までお付き合いください。

本連載のゴール

Laravel+Filamentを使い、DockerでMySQLデータベースを立て、ローカルで開発環境が利用できる&CSVダウンロード機能を利用できるようになるまで整える。

対象読者

前回のおさらい

第1回の記事では、ローカルでの開発環境構築をひとまず完了したかと思います。

http://localhost/admin/login

にアクセスすれば、管理画面にログインでき、ログイン後はダッシュボードが表示できるところまでをご紹介しました。今日はそこから始めていきます。

filament4.png

画面構築

今回はPostsというテスト用のテーブルを作り、ブログ記事のように入稿できるシステムを構築していきます。

マイグレーションファイルの作成

sail artisan make:migration create_posts_table

でマイグレーションファイルを作成。

用意したLaravelのmigrationファイルは以下になります。

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('body');
            $table->integer('type')->comment('0:blog 1:Tips 2:Other');
            $table->dateTime('published')->nullable();
            $table->integer('delete_flg')->default(0)->comment('削除フラグ');
            $table->timestamps();
        });
    }


    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('posts');
    }
};

sail artisan migrate

このコマンドを実行して、あらかじめLaravel Sail(Docker)上のMySQLデータベースにテーブルを作っておきます。

実際にできていることをTablePlus(MySQL接続アプリ)から確認。

実際にできていることをTablePlus(MySQL接続アプリ)から確認。

モデルの作成・前提を整える

モデルの作成

以下のコマンドを実行します

sail artisan make:model Post

ガード割当を無効にする

公式サイトの記述にしたがい、app/Providers/AppServiceProvider.phpの一括割当を無効にします。

一括割当=Key-Valueの配列を渡すことで、丸ごと中身を更新できるような方法は無効にするということです。具体的にどのようなケースで一括割当が弊害になるかは、体感としてまだ分かっていませんが、従います。

まだドキュメントに説明をこのガイドでは簡潔にするため、とありますので、後で戻すのかもしれません。

use Illuminate\Database\Eloquent\Model;
 
public function boot(): void
{
    Model::unguard();
}

「リソース」を作る

Postというテーブルを、*Filamentで呼べるようにするための必要なファイル=Resource リソースを自動作成する コマンドがあり、実行します。

 % php artisan make:filament-resource Post

   INFO  Filament resource [app/Filament/Resources/PostResource.php] created successfully.

このとおり、app/Filament/Reosources以下に

.
+-- PostResource.php
+-- PostResource
|   +-- Pages
|   |   +-- CreatePost.php
|   |   +-- EditPost.php
|   |   +-- ListPost.php

管理画面によくある構成の、

と対応するらしきファイルが自動でババっと生成されました。

この時点でhttp://localhost/adminを再度訪問すると、Postsという画面ができています。

filament201.png

しかし、中身はまだ空でした。

一覧画面

一覧画面

作成画面

作成画面

ここに、順次必要なパーツを定義して追加していくのだと思うと、Wordpressのソースコードによってサクサク作っていける版 みたいな感じでわかりやすそうです...

ほぼ**[モデル名]Resources.php** に定義を書いていく形で、最低限の画面をスカフォールディングするだけなら学習コストは低そうです。(逆に難しくした時の書き味が気になります。。)

作成画面にパーツを追加

先ほどのPostにタイトル欄の入力フォームを追加します。公式サイトの例に沿って、以下のようにPostResource.phpに書いていきます。

元々空になっているformメソッドに記述を入れていく感じです。Beforeがこちら。

    public static function form(Form $form): Form
    {
        return $form
            ->schema([
                //
            ]);
    }

Afterはこちら。

    public static function form(Form $form): Form
    {
        return $form
            ->schema([
                # タイトル 通常の入力欄
                Forms\Components\TextInput::make('title')
                    ->required()
                    ->maxLength(255),
                # 記事タイプ select box
                Forms\Components\Select::make('type')
                    ->options([
                        '0' => '通常',
                        '1' => 'Tips',
                        '2' => 'その他'
                    ]),
                # 投稿日時 入力なしで下書きとすることもできるが、入力した場合には現在以降を指定しないとエラー
                Forms\Components\DateTimePicker::make('published')
                    ->minDate(now()),
            ]);
    }

このようにバリデーションまで入れました。

追記して、ブラウザをリロードするだけ で表示が変わりました。

これはいい感じですね

これはいい感じですね

必要項目を入力するとレコードが無事できました。ただ、一覧にタイトルなど必要な表示がまだありません。

一覧画面に表示項目を追加

PostResource.phptable()メソッドを以下のように変えて、表示ができるようにします。

    public static function table(Table $table): Table
    {
        return $table
            ->columns([
                Tables\Columns\TextColumn::make('title'),
                Tables\Columns\TextColumn::make('published'),
            ])
            ->filters([
                // 下記のようにすると、投稿済みのもののみ絞り込める
                //Tables\Filters\Filter::make('published')
                //    ->query(fn (Builder $query): Builder => $query->whereNotNull('published')),

            ])
            ->actions([
                // 編集画面へのリンクなど、単発レコードへのリンクが出せる
                Tables\Actions\EditAction::make(),
            ])
            ->bulkActions([
                // 一斉削除など、まとめてアクションを行える
                Tables\Actions\BulkActionGroup::make([
                    Tables\Actions\DeleteBulkAction::make(),
                ]),
            ]);
    }
項目が見えました

項目が見えました

無事、表示ができました。

他にも、

ができるとのこと。この辺りは作り込んでいくとより分かってくると思います。とりあえず本日はCRUD の最低限ができた、ということでここまでとします。

補足: Livewireについて

Filamentは、Laravel Livewireを土台にして利用して作られています。

公式ページによるとLivewireとは

Livewire is a full-stack framework for Laravel that makes building dynamic interfaces simple, without leaving the comfort of Laravel.

>LivewireはLaravelのためのフルスタックフレームワークで、Laravelの快適さをそのままに、ダイナミックなインターフェースを簡単に構築できます。

とのこと。

要するにLaravelの利便性・拡張性はそのまま、さらに開発しやすくするフレームワークのようです。

今回はLivewireについては深掘りしないですが、今後時間があればこれもフルスクラッチでプロジェクトを立ち上げてみて試してみたいなと思っています。

まとめ

次回の第3回は、CSV一括ダウンロード機能について実装を行い、丁寧に解説を行います。 宜しければ最後までお付き合いいただけますととても嬉しいです。


2023/12/08追記。第3回を投稿しました!

参考記事:

モルドスプーンアイコン


連載記事をお読みいただきありがとうございました!
引き続き当ブログをよろしくお願いいたします。