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 路径会更方便。你可能希望为应用的「admin」区域使用单独的 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'));创建路由
你可以通过在任一 Folio 挂载目录中放置 Blade 模板来创建 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 目录内再创建一层或多层目录来创建嵌套路由。例如,要创建可通过 /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>要捕获多个片段,可以在被包裹的片段前加上三个点 ...:
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 模型,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 的页面会尝试通过 slug 列(而不是 id 列)解析绑定的模型。
在 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 页面定义和路由名称被正确缓存,从而获得最佳性能。