Laravel Folio
イントロダクション
Laravel Folioは、Laravelアプリケーションのルーティングを簡素化するために設計された、強力なページベースのルータです。Laravel Folioを使えば、アプリケーションのresources/views/pagesディレクトリ内にBladeテンプレートを作成するだけで、簡単にルートを生成できます。
たとえば、/greeting URLでアクセスできるページを作成するには、アプリケーションのresources/views/pagesディレクトリにgreeting.blade.phpファイルを作成するだけです。
1<div>2 Hello World3</div>
インストール
使い始めるには、Composerパッケージマネージャを使用してプロジェクトにFolioをインストールします。
1composer require laravel/folio
Folioをインストールしたら、folio:install Artisanコマンドを実行します。これにより、Folioのサービスプロバイダがアプリケーションにインストールされます。このサービスプロバイダは、Folioがルート/ページを検索するディレクトリを登録します。
1php artisan folio:install
ページのパス/URI
デフォルトでは、Folioはアプリケーションのresources/views/pagesディレクトリからページを提供しますが、Folioサービスプロバイダのbootメソッドでこれらのディレクトリをカスタマイズできます。
たとえば、同じLaravelアプリケーションで複数のFolioパスを指定すると便利な場合があります。アプリケーションの「admin」領域用にFolioページのディレクトリを別に用意し、アプリケーションの残りのページには別のディレクトリを使用したい場合などです。
これは、Folio::pathメソッドとFolio::uriメソッドを使用して実現できます。pathメソッドは、受信HTTPリクエストをルーティングする際にFolioがページをスキャンするディレクトリを登録し、uriメソッドはそのページのディレクトリの「ベースURI」を指定します。
1use Laravel\Folio\Folio; 2 3Folio::path(resource_path('views/pages/guest'))->uri('/'); 4 5Folio::path(resource_path('views/pages/admin')) 6 ->uri('/admin') 7 ->middleware([ 8 '*' => [ 9 'auth',10 'verified',11 12 // ...13 ],14 ]);
サブドメインルーティング
受信リクエストのサブドメインに基づいてページにルートすることもできます。たとえば、admin.example.comからのリクエストを、他のFolioページとは異なるページディレクトリにルーティングしたい場合などです。これは、Folio::pathメソッドを呼び出した後にdomainメソッドを呼び出すことで実現できます。
1use Laravel\Folio\Folio;2 3Folio::domain('admin.example.com')4 ->path(resource_path('views/pages/admin'));
domainメソッドでは、ドメインまたはサブドメインの一部をパラメータとしてキャプチャすることもできます。これらのパラメータは、ページテンプレートにインジェクトされます。
1use Laravel\Folio\Folio;2 3Folio::domain('{account}.example.com')4 ->path(resource_path('views/pages/admin'));
ルートの作成
FolioでマウントされたディレクトリのいずれかにBladeテンプレートを配置することで、Folioルートを作成できます。デフォルトでは、Folioはresources/views/pagesディレクトリをマウントしますが、Folioサービスプロバイダのbootメソッドでこれらのディレクトリをカスタマイズできます。
BladeテンプレートをFolioでマウントされたディレクトリに配置すると、すぐにブラウザからアクセスできます。たとえば、pages/schedule.blade.phpに配置されたページは、ブラウザでhttp://example.com/scheduleとしてアクセスできます。
すべてのFolioページ/ルートのリストを素早く表示するには、folio:list Artisanコマンドを実行します。
1php artisan folio:list
ネストしたルート
Folioのディレクトリ内に1つ以上のディレクトリを作成することで、ネストしたルートを作成できます。たとえば、/user/profileでアクセスできるページを作成するには、pages/userディレクトリ内にprofile.blade.phpテンプレートを作成します。
1php artisan folio:page user/profile2 3# pages/user/profile.blade.php → /user/profile
インデックスルート
特定のページをディレクトリの「インデックス」にしたい場合があります。Folioディレクトリ内にindex.blade.phpテンプレートを配置すると、そのディレクトリのルートへのリクエストはすべてそのページにルーティングされます。
1php artisan folio:page index2# pages/index.blade.php → /3 4php artisan folio:page users/index5# pages/users/index.blade.php → /users
ルートパラメータ
多くの場合、受信リクエストのURLのセグメントをページにインジェクトして、それらを操作する必要があります。たとえば、表示されているプロファイルのユーザーの「ID」にアクセスする必要があるかもしれません。これを実現するには、ページのファイル名のセグメントを角括弧で囲みます。
1php artisan folio:page "users/[id]"2 3# pages/users/[id].blade.php → /users/1
キャプチャしたセグメントは、Bladeテンプレート内で変数としてアクセスできます。
1<div>2 User {{ $id }}3</div>
複数のセグメントをキャプチャするには、囲んだセグメントの前に3つのドット...を付けます。
1php artisan folio:page "users/[...ids]"2 3# pages/users/[...ids].blade.php → /users/1/2/3
複数のセグメントをキャプチャする場合、キャプチャされたセグメントは配列としてページにインジェクトされます。
1<ul>2 @foreach ($ids as $id)3 <li>User {{ $id }}</li>4 @endforeach5</ul>
ルートモデル結合
ページテンプレートのファイル名のワイルドカードセグメントが、アプリケーションのEloquentモデルのいずれかに対応する場合、Folioは自動的にLaravelのルートモデル結合機能を利用し、解決されたモデルインスタンスをページにインジェクトしようとします。
1php artisan folio:page "users/[User]"2 3# pages/users/[User].blade.php → /users/1
キャプチャしたモデルは、Bladeテンプレート内で変数としてアクセスできます。モデルの変数名は「キャメルケース」に変換されます。
1<div>2 User {{ $user->id }}3</div>
キーのカスタマイズ
id以外のカラムを使用して、結合されたEloquentモデルを解決したい場合があります。そのためには、ページのファイル名でカラムを指定します。たとえば、[Post:slug].blade.phpというファイル名のページは、idカラムの代わりにslugカラムを介して結合モデルを解決しようとします。
Windowsでは、モデル名とキーを区切るために-を使用する必要があります:[Post-slug].blade.php。
モデルの場所
デフォルトでは、Folioはアプリケーションのapp/Modelsディレクトリ内でモデルを検索します。しかし、必要に応じて、テンプレートのファイル名で完全修飾モデルクラス名を指定できます。
1php artisan folio:page "users/[.App.Models.User]"2 3# pages/users/[.App.Models.User].blade.php → /users/1
ソフトデリートされたモデル
デフォルトでは、暗黙のモデル結合を解決する際に、ソフトデリートされたモデルは取得されません。しかし、必要であれば、ページのテンプレート内でwithTrashed関数を呼び出すことで、Folioにソフトデリートされたモデルを取得するように指示できます。
1<?php 2 3use function Laravel\Folio\{withTrashed}; 4 5withTrashed(); 6 7?> 8 9<div>10 User {{ $user->id }}11</div>
レンダーフック
デフォルトでは、FolioはページBladeテンプレートのコンテンツを受信リクエストへのレスポンスとして返します。しかし、ページのテンプレート内でrender関数を呼び出すことで、レスポンスをカスタマイズできます。
render関数は、FolioによってレンダーされるViewインスタンスを受け取るクロージャを引数に取ります。これにより、ビューに追加のデータを加えたり、レスポンス全体をカスタマイズしたりできます。Viewインスタンスを受け取るだけでなく、追加のルートパラメータやモデル結合もrenderクロージャに提供されます。
1<?php 2 3use App\Models\Post; 4use Illuminate\Support\Facades\Auth; 5use Illuminate\View\View; 6 7use function Laravel\Folio\render; 8 9render(function (View $view, Post $post) {10 if (! Auth::user()->can('view', $post)) {11 return response('Unauthorized', 403);12 }13 14 return $view->with('photos', $post->author->photos);15}); ?>16 17<div>18 {{ $post->content }}19</div>20 21<div>22 This author has also taken {{ count($photos) }} photos.23</div>
名前付きルート
name関数を使用して、特定のページのルートに名前を指定できます。
1<?php2 3use function Laravel\Folio\name;4 5name('users.index');
Laravelの名前付きルートと同様に、route関数を使用して、名前が割り当てられたFolioページへのURLを生成できます。
1<a href="{{ route('users.index') }}">2 All Users3</a>
ページにパラメータがある場合は、その値をroute関数に渡すだけです。
1route('users.show', ['user' => $user]);
ミドルウェア
特定のページにミドルウェアを適用するには、ページのテンプレート内でmiddleware関数を呼び出します。
1<?php 2 3use function Laravel\Folio\{middleware}; 4 5middleware(['auth', 'verified']); 6 7?> 8 9<div>10 Dashboard11</div>
または、ページのグループにミドルウェアを割り当てるには、Folio::pathメソッドを呼び出した後にmiddlewareメソッドをチェーンします。
ミドルウェアを適用するページを指定するために、ミドルウェアの配列は、適用されるべきページの対応するURLパターンをキーとして使用できます。*文字はワイルドカード文字として利用できます。
1use Laravel\Folio\Folio; 2 3Folio::path(resource_path('views/pages'))->middleware([ 4 'admin/*' => [ 5 'auth', 6 'verified', 7 8 // ... 9 ],10]);
ミドルウェアの配列にクロージャを含めることで、インラインの匿名ミドルウェアを定義できます。
1use Closure; 2use Illuminate\Http\Request; 3use Laravel\Folio\Folio; 4 5Folio::path(resource_path('views/pages'))->middleware([ 6 'admin/*' => [ 7 'auth', 8 'verified', 9 10 function (Request $request, Closure $next) {11 // ...12 13 return $next($request);14 },15 ],16]);
ルートキャッシュ
Folioを使用する際は、常にLaravelのルートキャッシュ機能を活用する必要があります。Folioはroute:cache Artisanコマンドをリッスンし、Folioのページ定義とルート名が最高のパフォーマンスのために適切にキャッシュされるようにします。