Laravelでエラーページをカスタマイズしようと思って調べてみると、resources/views/errorsフォルダに40xや50xのHTTPエラーのステータスコード毎にファイルを作れと書いてある。
表示されるエラーはほとんど場合決まってはいるものの、複数に対応するのはとても面倒なので、LaravelのBladeテンプレートを使ってエラーページを共通化することにしました。
エラーページの設置場所
Laravelでは、どのようなページでもお決まりの[resources/views]以下に保存されていますが、エラーページも例外ではありません。
通常はこのように、ステータスコード毎にエラーページも増えていきます。
1 2 3 4 |
resources/views/errors/40x.blade.php ... resources/views/errors/50x.blade.php ... |
これではエラーページが増えすぎて、管理が複雑になってしまうので、この1つのエラーページで済むように共通化します。
1 |
resources/views/errors.blade.php |
エラーメッセージを作成する
まずは、各エラーページに必要なエラーメッセージを共通のファイルに作成します。
以前、バリデーションメッセージファイルなどを日本語化しましたが、同じ要領でHTTPエラーのステータスコード毎にメッセージを作成します。
まずは、こちらのサイトを参考にエラーメッセージファイルを作りました。
できたものはGitHubに置いていますので、ご自由にお使いください。
共通ページへ遷移させる
次にステータスコードから上記で作成したメッセージを取得し、共通ページへ遷移させます。
変更するのは、Handler.phpのrender()関数内のみです。
app/Exceptions/Handler.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
/** * 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
@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系とそれ以外を赤色で色分けしています。
こんな感じ。
コメント