🐙

バックエンドエンジニアがAdminLTE + livewireでjsを一切書かずphpだけで動的管理画面を作ってみた AdminLTE編

2023/10/16に公開

この記事について

業務でLaravelを使っていた際に、管理画面はlaravel-adminやfilamentなどのライブラリを使っていました。
これらはコードを自動生成してくれるためかなり助かる反面、細かい画面調整や機能追加が難しい部分もあり、お客さまの要望に対応するのが難しい場面がありました。

それならいっそ、tailwind + LaravelBladeで作成してはどうかと思い試してみたのですが、やはり一から画面レイアウトを作るのは、tailwindやBootstrapを使ったとしても少し難易度が高く感じました。
個人的には、特にメッセージや文言の配置をいい感じに配置させる部分が難しく感じました。
また、実装しているうちにBladeのコードもコンポーネント化して使いまわしたいという思いが湧きました。

そこで、コンポーネント化ができるライブラリはないかと探したところ、AdminLTE + livewire で管理画面を作成するという手法に行き当たり、試しに作成してみました。

使用マシン/ツール

  • macOS Ventura ver13.6
  • Docker Desktop ver4.23.0
  • Laravel Framework 10.25.2
  • Laravel AdminLTE 3.2.0

作成してみて

先に簡単に感想を述べますと

adminLTE

tailwindで作ったレイアウトと同等以上のものが簡単に実現でき、Bootstrapの機能をそのまま使えるので扱いやすい。

livewire

jsの処理を書かずにSPA同等の画面を実装可能で、LaravelBladeの実装を把握しているなら学習コストもそこまでかからず実装できる。

といった感じでした。

Laravel AdminLTEとlivewireについて

Laravel AdminLTEとは

Bootstrapをベースにした管理画面テンプレートになります。
Bootstrapの機能をそのまま使うことができるので、シンプルなデザインであれば苦労せず組み込むことが可能です。
https://github.com/jeroennoten/Laravel-AdminLTE

livewireとは

ReactやVueなどを使わず、PHPとHTML、少しのJavaScriptでリアルタイムな更新ができる画面を作成することが可能になります。
機能に応じてコンポーネント化をすることで、再利用性が高めることもできます。
https://github.com/livewire/livewire
https://livewire.laravel.com/docs/quickstart

今回はこの2つを組み合わせて、管理画面を作成します。
また、Dockerで環境構築していきます。

ベースにした環境はこちらを使用しました。
docker-laravel
https://github.com/ucan-lab/docker-laravel

1. docker-laravelをインストール

公式のドキュメントどおりにインストールを実行します。
https://github.com/ucan-lab/docker-laravel#laravel-install

http://localhost/ が見れれば大丈夫です。

2. Laravel AdminLTEをインストール

https://github.com/jeroennoten/Laravel-AdminLTE/wiki/Installation
インストールコマンドはappコンテナ内で実行します。
下記コマンドを実行していきます。

-- appコンテナに入る
$ make app 
-- Laravel AdminLTEをインストール
root@814e05c78961:/workspace# composer require jeroennoten/laravel-adminlte
-- AdminLTEテンプレートと依存関係(Bootstrapなど)をインストール
root@814e05c78961:/workspace# php artisan adminlte:install
-- ログイン画面のテンプレートをインストール
root@814e05c78961:/workspace# php artisan adminlte:install --only=auth_views
-- appコンテナから抜ける
root@814e05c78961:/workspace# exit

コマンド実行後、下記にファイルやディレクトリが生成されていればインストールは完了です。
src/config/adminlte.php
src/lang/
src/public/vendor/
src/resources/views/auth/

src/lang/ は各国の言語設定ファイルが生成されているので、不要なものは削除してよさそうです。
今回は日本語のみ使用するので、ja以外のディレクトリは削除します。

3. ログイン画面を表示する

まずはログイン画面を表示してみます。
routes/web.phpに下記を追記します。

routes/web.php
+ Route::get('/admin/login', function () {
+     return view('/auth/login');
+ })
+    ->name('admin.login');

auth/loginは前述のコマンドでインストールされたログイン画面のテンプレートで、src/resources/views/auth/login.blade.phpを参照しています。

追記後、下記URLにアクセスするとログイン画面が表示されます。
http://localhost/admin/login

4. ホーム画面を作成する

https://github.com/jeroennoten/Laravel-AdminLTE/wiki/Usage
次に、ログイン後のホーム画面を表示するため、対応するbladeファイルを作成していきます。
下記内容で src/resources/views/admin/home.blade.php を作成します。

src/resources/views/home.blade.php
@extends('adminlte::page')

@section('title', 'Dashboard')

@section('content_header')
    <h1>Dashboard</h1>
@stop

@section('content')
    <p>Welcome to this beautiful admin panel.</p>
@stop

@section('css')
    <link rel="stylesheet" href="/css/admin_custom.css">
@stop

@section('js')
    <script> console.log('Hi!'); </script>
@stop

routes/web.phpに下記を追記します。

routes/web.php
+ Route::get('/admin/home', function () {
+     return view('/admin/home');
+ })->name('admin.home');

追記後、下記URLにアクセスするとホーム画面が表示されます。
http://localhost/admin/home

5. ログイン認証を実装する

この状態だと画面を表示するだけで、ログイン認証は実装されていないので、実装してみたいと思います。
laravel/uiやLaravel-Breezeを使うと簡単に実装できるみたいなのですが、今回は手動で組み込んでいます。
すでに認証機能周りが実装済みであれば、下記の手順は不要です。

5-1. 管理者用のテーブルを作成する

まずはログインできるユーザーを管理するテーブルを作成します。
下記コマンドを実行し、マイグレーションファイルを作成します。

$ docker compose exec app php artisan make:migration create_admin_users_table

  INFO  Migration [database/migrations/2023_10_03_064137_create_admin_users_table.php] created successfully.

次に、マイグレーションファイルを下記のように編集します。

src/database/migrations/2023_10_03_064137_create_admin_users_table.php
+use Carbon\CarbonImmutable;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Schema;
~省略~
  public function up(): void
  {
    Schema::create('admin_users', function (Blueprint $table) {
        $table->id();
+       $table->string('name');
+       $table->string('email')->unique();
+       $table->string('password');
        $table->timestamps();
    });
+   $now = CarbonImmutable::now();
+   DB::table('admin_users')->insert([
+       'name' => 'admin',
+       'email' => 'admin@example.com',
+       'password' => Hash::make('adminltepassword'),
+       'created_at' => $now,
+       'updated_at' => $now,
+   ]);

管理者用のテーブルの作成と、初期管理ユーザーを作成しています。
本来ならデータ登録はSeederを使うのが望ましいと思いますが、今回は検証がメインなのでマイグレーションで一緒に登録しています。
編集後、下記コマンドを実行します。

$ make migrate // マイグレーション実行
docker compose exec app php artisan migrate

   INFO  Running migrations.  

  2023_10_03_064137_create_admin_users_table ................................................... 156ms DONE

5-2. configの編集

config/auth.phpを下記のように編集します。

src/config/auth.php
    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
+       'admin' => [
+           'driver' => 'session',
+           'provider' => 'admin_users',
+       ],
    ],
    ~~省略~~
    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Models\User::class,
        ],
+       'admin_users' => [
+           'driver' => 'eloquent',
+           'model' => App\Models\Admin\AdminUser::class,
+       ],

デフォルトの状態ですと、ログイン処理のルーティングがloginとなっているので、ログインするとエラーになります。
これを解決するため、config/adminlte.phpURLsを下記のように編集します。

src/config/adminlte.php
-    'dashboard_url' => 'home',
+    'dashboard_url' => 'admin/home',
-    'login_url' => 'login',
+    'login_url' => 'admin/auth',

5-3. モデルとコントローラーを生成する

下記コマンドを実行します。

$ docker compose exec app php artisan make:model Admin/AdminUser
   INFO  Model [app/Models/Admin/AdminUser.php] created successfully. 

$ docker compose exec app php artisan make:controller Admin/LoginController
   INFO  Controller [app/Http/Controllers/Admin/LoginController.php] created successfully. 

モデルを下記のように編集します。

src/app/Models/Admin/AdminUser.php
-class AdminUser extends Model
+class AdminUser extends \Illuminate\Foundation\Auth\User
{
    use HasFactory;

+   protected $table = 'admin_users';

+   protected $hidden = [
+       'password'
+   ];

+   protected $fillable = [
+       'name',
+       'email',
+       'password'
+   ];
}

コントローラーに下記メソッドを作成します。

src/app/Http/Controllers/Admin/LoginController.php
    public function authenticate(Request $request): RedirectResponse
    {
        $credentials = $request->validate(
            [
                // 入力内容のチェック
                'email' => ['required', 'email'],
                'password' => ['required'],
            ],
            [
                'email.required' => 'メールアドレスを入力してください。',
                'email.email' => 'メールアドレスの形式で入力してください。',
                'password.required' => 'パスワードを入力してください。',
            ]
        );

        if (Auth::guard('admin')->attempt($credentials)) {
            $request->session()->regenerate();
            // 管理者ホーム画面へリダイレクト
            return redirect()->intended('/admin/home');
        }

        return back()->withErrors([
            'login_error' => 'メールアドレスかパスワードが間違っています。',
        ]);
    }

5-4. ルーティングの追加と編集

routes/web.phpに下記を追記、編集します。

routes/web.php
+Route::post(
+    '/admin/auth',
+    '\App\Http\Controllers\Adminlte\LoginController@authenticate'
+)->name('admin.auth');

+Route::middleware(['auth:admin'])->group(function () {
    // ログイン認証が通ってない場合、URLで直接homeにアクセスしても画面が見れないように
    Route::get('/admin/home', function () {
        return view('/admin/home');
    })->name('admin.home');
+});

上記まで実装したら、マイグレーションで作成したユーザーを使ってログインできるようになります。

5-5. ログアウト処理を実装する

せっかくなのでログアウト処理も実装します。
LoginControllerに下記メソッドを追加します。

src/app/Http/Controllers/Admin/LoginController.php
    public function logout(Request $request): RedirectResponse
    {
        Auth::guard('admin')->logout();

        $request->session()->invalidate();

        $request->session()->regenerateToken();

        return redirect()->route('admin.login');
    }

config/routes.phpに下記を追記します。

routes/web.php
Route::post(
    '/admin/logout',
    '\App\Http\Controllers\Admin\LoginController@logout'
)->name('admin.logout');

adminlte.phpの下記を編集します。

src/config/adminlte.php
'logout_url' => 'admin/logout',

上記まで実装すると、ログイン後のダッシュボード右上からログアウトが実行できます。
ログアウト後はログイン画面にリダイレクトされます。

本来ならログインしてない場合にホーム画面にアクセスしたらログイン画面にリダイレクトするなどの処理を入れるべきですが、今回は割愛します。

まとめ

AdminLTEは管理画面として整ったデザインがすぐに使えるのと、独自のBootstrapのスタイルを当ててもレイアウト崩れが起きず扱いやすかったです。
特に独自のスタイルを当てることができるのは、お客さまからレイアウト要望があっても対応しやすい印象でした。
次回はlivewireも使って、管理画面の機能を実装していきます。

参考

https://qiita.com/yuu_1st/items/d580fb4cb10b5fcc85d9

EGSTOCK,Inc.

Discussion