Cake 2.x はデフォルトで、ステータスコード 4xx台のテンプレートに View/Error/error400.ctp を使用します。

Refer: https://github.com/cakephp/cakephp/blob/2.x/lib/Cake/Error/ExceptionRenderer.php#L94-L132

この記事では、ステータスコード 4xx台のテンプレートを個別にする設定する方法を紹介します。

今回、1つの例として UnauthorizedException() の例外が投げられた際に View/Error/error401.ctp を使用するように変更します。

Let’s Start!

方針として

  1. Controller#appError($exception) でテンプレートを指定 https://github.com/cakephp/cakephp/blob/2.x/lib/Cake/Error/ExceptionRenderer.php#L98
  2. ExceptionRenderer.php を拡張

の 2通り思いついたのですが、

http://book.cakephp.org/2.0/en/development/exceptions.html#extending-and-implementing-your-own-exception-handlers

にあるように ExceptionRender に使用するクラスを指定すことができるので、「2. ExceptionRenderer.php を拡張」を採用します。

MyCustomExceptionRenderer.php

diff --git a/Lib/Error/MyCustomExceptionRenderer.php b/Lib/Error/MyCustomExceptionRenderer.php
new file mode 100644
index 0000000..949a828
--- /dev/null
+++ b/Lib/Error/MyCustomExceptionRenderer.php
@@ -0,0 +1,32 @@
+<?php
+App::uses('ExceptionRenderer', 'Error');
+
+/**
+ * Exception Renderer.
+ */
+class MyCustomExceptionRenderer extends ExceptionRenderer {
+
+/**
+ * Display a unauthorized page.
+ *
+ * @param Exception $error The exception to render.
+ * @return void
+ */
+ public function unauthorized($error) {
+ $message = $error->getMessage();
+ if (!Configure::read('debug') && $error instanceof CakeException) {
+ $message = __d('cake', 'Unauthorized');
+ }
+ $url = $this->controller->request->here();
+ $this->controller->response->statusCode($error->getCode());
+ $this->controller->set(array(
+ 'name' => h($message),
+ 'message' => h($message),
+ 'url' => h($url),
+ 'error' => $error,
+ '_serialize' => array('name', 'message', 'url')
+ ));
+ $this->_outputMessage('error401');
+ }
+
+}

ExceptionRenderに使用するクラスを指定

$ echo "Configure::write('Exception.renderer', 'MyCustomExceptionRenderer');" >> Config/bootstrap.php

テンプレート作成

$ touch View/Errors/error401.ctp

できました!

あとは、UnauthorizedException() の例外を投げればおkです。

Todo

  • テストの書き方

Reference Sites