Laravelでエラーページをカスタマイズしようと思って調べてみると、resources/views/errorsフォルダに40xや50xのHTTPエラーのステータスコード毎にファイルを作れと書いてある。
表示されるエラーはほとんど場合決まってはいるものの、複数に対応するのはとても面倒なので、LaravelのBladeテンプレートを使ってエラーページを共通化することにしました。
エラーページの設置場所
Laravelでは、どのようなページでもお決まりの[resources/views]以下に保存されていますが、エラーページも例外ではありません。
通常はこのように、ステータスコード毎にエラーページも増えていきます。
resources/views/errors/40x.blade.php
...
resources/views/errors/50x.blade.php
...
これではエラーページが増えすぎて、管理が複雑になってしまうので、この1つのエラーページで済むように共通化します。
resources/views/errors.blade.php
エラーメッセージを作成する
まずは、各エラーページに必要なエラーメッセージを共通のファイルに作成します。
以前、バリデーションメッセージファイルなどを日本語化しましたが、同じ要領でHTTPエラーのステータスコード毎にメッセージを作成します。
まずは、こちらのサイトを参考にエラーメッセージファイルを作りました。
できたものはGitHubに置いていますので、ご自由にお使いください。
共通ページへ遷移させる
次にステータスコードから上記で作成したメッセージを取得し、共通ページへ遷移させます。
変更するのは、Handler.phpのrender()関数内のみです。
app/Exceptions/Handler.php
/**
* Render an exception into an HTTP response.
*
* @param IlluminateHttpRequest $request
* @param Exception $exception
* @return IlluminateHttpResponse
*/
public function render($request, Exception $exception)
{
if($this->isHttpException($exception)) {
$s['status'] = $exception->getStatusCode();
$m = (__('errors.' . $s['status'])) ? __('errors.' . $s['status']) : __('errors.999');
$errors = ($s + $m);
return response()->view('errors', compact('errors'), $errors['status']);
}
return parent::render($request, $exception);
}
解説と注意点
ちょっとハマったところですが、HttpException
で判定しておかないとログインエラーなども拾ってしまってgetStatusCode()
で落ちるので、必ず$this->isHttpException($exception)
で判定しておいてください。getStatusCode()
でステータスコードを取得できます。__()
のヘルパー関数を使って上記で作成したメッセージを取得し、ステータスコードと一緒に$errors
変数に入れ、compact('errors')
で共通のエラーページ(Blade)に渡します。
共通のエラーページを表示
共通のエラーページを作成して、上記で渡されたエラーメッセージを表示します。
resources/views/errors.blade.php
@extends('layouts.app')
@section('content')
{!! $color = (substr($errors['status'], 0, 1) == 4) ? 'warning' : 'danger' ; !!}
<div class="content-wrapper">
<!-- Content Header (Page header) -->
<section class="content-header">
<h1>
{{ $errors['title'] }}
</h1>
<ol class="breadcrumb">
<li><a href="{{ route('home') }}"><i class="fa fa-dashboard"></i> ダッシュボード</a></li>
<li class="active">{{ $errors['title'] }}</li>
</ol>
</section>
<!-- Main content -->
<section class="content">
<div class="error-page">
<h2 class="headline text-{{ $color }}"> {{ $errors['status'] }}</h2>
<div class="error-content">
<h3><i class="fa fa-warning text-{{ $color }}"></i> {{ $errors['title'] }}</h3>
<p>{{ $errors['message'] }}</p>
<small>
エラーによりページが表示できません。<br />
<a href="{{ route('home') }}">ダッシュボード</a>に戻って再度試すか、システム管理者にご連絡ください。
</small>
</div>
<!-- /.error-content -->
</div>
<!-- /.error-page -->
</section>
<!-- /.content -->
</div>
@endsection
解説とポイント
$errors
配列に入れたエラーメッセージを表示しています。
ステータスコードによって40x系を黄色、50x系とそれ以外を赤色で色分けしています。
こんな感じ。
- Original:https://minory.org/laravel-custom-errors-page.html
- Source:Minory
- Author:管理者