メインコンテンツまでスキップ

Laravel Folio

はじめに

Laravel Folio は、Laravelアプリケーション内のルーティングを簡素化するために設計された強力なページベースのルーターです。Laravel Folioを使用すると、resources/views/pagesディレクトリ内にBladeテンプレートを作成するだけで、ルートの生成が簡単になります。

たとえば、/greeting URLでアクセス可能なページを作成するには、アプリケーションのresources/views/pagesディレクトリにgreeting.blade.phpファイルを作成するだけです:

<div>
Hello World
</div>

インストール

まずは、Composerパッケージマネージャーを使用してプロジェクトにFolioをインストールしてください:

composer require laravel/folio

Folioをインストールした後は、folio:install Artisanコマンドを実行することができます。これにより、Folioのサービスプロバイダーがアプリケーションに登録されます。このサービスプロバイダーは、Folioがルート/ページを検索するディレクトリを登録します:

php artisan folio:install

ページパス / URI

デフォルトでは、Folioはアプリケーションのresources/views/pagesディレクトリからページを提供しますが、Folioサービスプロバイダーのbootメソッドでこれらのディレクトリをカスタマイズすることができます。

たとえば、同じLaravelアプリケーション内で複数のFolioパスを指定することが便利な場合があります。アプリケーションの「管理者」エリア用に別のFolioページディレクトリを指定したい場合など、アプリケーションの他のページ用に別のディレクトリを使用したい場合があります。

これは、Folio::pathおよびFolio::uriメソッドを使用して実現できます。pathメソッドは、Folioが着信HTTPリクエストをルーティングする際にページをスキャンするディレクトリを登録し、uriメソッドはそのページディレクトリの「ベースURI」を指定します。

use Laravel\Folio\Folio;

Folio::path(resource_path('views/pages/guest'))->uri('/');

Folio::path(resource_path('views/pages/admin'))
->uri('/admin')
->middleware([
'*' => [
'auth',
'verified',

// ...
],
]);

サブドメインルーティング

着信リクエストのサブドメインに基づいてページにルーティングすることもできます。たとえば、admin.example.comからのリクエストを、他のFolioページとは異なるページディレクトリにルーティングしたい場合があります。これは、Folio::pathメソッドを呼び出した後にdomainメソッドを呼び出すことで実現できます:

use Laravel\Folio\Folio;

Folio::domain('admin.example.com')
->path(resource_path('views/pages/admin'));

domainメソッドを使用すると、ドメインやサブドメインの一部をパラメータとしてキャプチャすることもできます。これらのパラメータは、ページテンプレートに挿入されます:

use Laravel\Folio\Folio;

Folio::domain('{account}.example.com')
->path(resource_path('views/pages/admin'));

ルートの作成

BladeテンプレートをFolioがマウントされたディレクトリのいずれかに配置することで、Folioルートを作成できます。デフォルトでは、Folioはresources/views/pagesディレクトリをマウントしますが、Folioサービスプロバイダのbootメソッドでこれらのディレクトリをカスタマイズすることができます。

BladeテンプレートがFolioがマウントされたディレクトリに配置されると、ブラウザから直接アクセスできます。たとえば、pages/schedule.blade.phpに配置されたページは、ブラウザでhttp://example.com/scheduleにアクセスできます。

すべてのFolioページ/ルートのリストをすばやく表示するには、folio:list Artisanコマンドを呼び出すことができます:

php artisan folio:list

ネストされたルート

Folioのディレクトリ内に1つ以上のディレクトリを作成することで、ネストされたルートを作成できます。たとえば、/user/profileからアクセス可能なページを作成するには、pages/userディレクトリ内にprofile.blade.phpテンプレートを作成します:

php artisan folio:page user/profile

# pages/user/profile.blade.php → /user/profile

インデックスルート

時々、特定のページをディレクトリの「インデックス」にしたい場合があります。Folioディレクトリ内にindex.blade.phpテンプレートを配置すると、そのディレクトリのルートへのすべてのリクエストがそのページにルーティングされます:

php artisan folio:page index
# pages/index.blade.php → /

php artisan folio:page users/index
# pages/users/index.blade.php → /users

ルートパラメータ

しばしば、着信リクエストのURLのセグメントをページに挿入して、それらとやり取りできるようにする必要があります。たとえば、表示されているプロフィールの「ID」にアクセスする必要があるかもしれません。これを実現するために、ページのファイル名のセグメントを角かっこで囲むことができます:

php artisan folio:page "users/[id]"

# pages/users/[id].blade.php → /users/1

キャプチャされたセグメントは、Bladeテンプレート内で変数としてアクセスできます:

<div>
User {{ $id }}
</div>

複数のセグメントをキャプチャする場合、カプセル化されたセグメントの前に3つのドット ... を付けることができます:

php artisan folio:page "users/[...ids]"

# pages/users/[...ids].blade.php → /users/1/2/3

複数のセグメントをキャプチャする場合、キャプチャされたセグメントは配列としてページに挿入されます:

<ul>
@foreach ($ids as $id)
<li>User {{ $id }}</li>
@endforeach
</ul>

ルートモデルバインディング

ページテンプレートのファイル名のワイルドカードセグメントが、アプリケーションのEloquentモデルの1つに対応している場合、Folioは自動的にLaravelのルートモデルバインディング機能を利用し、解決されたモデルインスタンスをページに挿入しようとします:

php artisan folio:page "users/[User]"

# pages/users/[User].blade.php → /users/1

キャプチャされたモデルは、Bladeテンプレート内で変数としてアクセスできます。モデルの変数名は "キャメルケース" に変換されます:

<div>
User {{ $user->id }}
</div>

キーのカスタマイズ

時々、id 以外のカラムを使用してバインドされたEloquentモデルを解決したい場合があります。その場合は、ページのファイル名でカラムを指定することができます。例えば、ファイル名が [Post:slug].blade.php のページは、id カラムではなく slug カラムを介してバインドされたモデルを解決しようとします。

Windowsでは、モデル名とキーを区切るために - を使用する必要があります:[Post-slug].blade.php

モデルの場所

デフォルトでは、Folioはアプリケーションの app/Models ディレクトリ内でモデルを検索します。ただし、必要に応じて、テンプレートのファイル名で完全修飾モデルクラス名を指定することができます:

php artisan folio:page "users/[.App.Models.User]"

# pages/users/[.App.Models.User].blade.php → /users/1

ソフトデリートされたモデル

デフォルトでは、ソフトデリートされたモデルは暗黙のモデルバインディングを解決する際に取得されません。ただし、必要な場合は、ページのテンプレート内で withTrashed 関数を呼び出すことで、Folioにソフトデリートされたモデルを取得するよう指示できます:

<?php

use function Laravel\Folio\{withTrashed};

withTrashed();

?>

<div>
User {{ $user->id }}
</div>

レンダーフック

デフォルトでは、FolioはページのBladeテンプレートの内容を着信リクエストへの応答として返します。ただし、ページのテンプレート内で render 関数を呼び出すことで、応答をカスタマイズすることができます。

render 関数は、Folio によってレンダリングされる View インスタンスを受け取るクロージャを受け入れ、ビューに追加のデータを追加したり、レスポンス全体をカスタマイズすることができます。View インスタンスを受け取るだけでなく、追加のルートパラメータやモデルバインディングも render クロージャに提供されます:

<?php

use App\Models\Post;
use Illuminate\Support\Facades\Auth;
use Illuminate\View\View;

use function Laravel\Folio\render;

render(function (View $view, Post $post) {
if (! Auth::user()->can('view', $post)) {
return response('Unauthorized', 403);
}

return $view->with('photos', $post->author->photos);
}); ?>

<div>
{{ $post->content }}
</div>

<div>
This author has also taken {{ count($photos) }} photos.
</div>

名前付きルート

name 関数を使用して、特定のページのルートに名前を指定することができます:

<?php

use function Laravel\Folio\name;

name('users.index');

Laravel の名前付きルートと同様に、route 関数を使用して、名前が割り当てられた Folio ページへの URL を生成することができます:

<a href="{{ route('users.index') }}">
All Users
</a>

ページにパラメータがある場合は、単純にそれらの値を route 関数に渡すことができます:

route('users.show', ['user' => $user]);

ミドルウェア

ページのテンプレート内で middleware 関数を呼び出すことで、特定のページにミドルウェアを適用することができます:

<?php

use function Laravel\Folio\{middleware};

middleware(['auth', 'verified']);

?>

<div>
Dashboard
</div>

または、複数のページにミドルウェアを割り当てるには、Folio::path メソッドを呼び出した後に middleware メソッドをチェーンすることができます。

ミドルウェアを適用するページを指定するには、ページの URL パターンを使用してミドルウェアの配列をキー付けすることができます。* 文字はワイルドカード文字として利用できます:

use Laravel\Folio\Folio;

Folio::path(resource_path('views/pages'))->middleware([
'admin/*' => [
'auth',
'verified',

// ...
],
]);

インラインで匿名のミドルウェアを定義するために、ミドルウェアの配列にクロージャを含めることができます:

use Closure;
use Illuminate\Http\Request;
use Laravel\Folio\Folio;

Folio::path(resource_path('views/pages'))->middleware([
'admin/*' => [
'auth',
'verified',

function (Request $request, Closure $next) {
// ...

return $next($request);
},
],
]);

ルートキャッシング

Folio を使用する際は、常に Laravel のルートキャッシング機能を活用する必要があります。Folio は、route:cache Artisan コマンドを監視して、Folio ページの定義とルート名が適切にキャッシュされ、最大のパフォーマンスが得られるようにします。