开发者

Cakephp - how to make error pages have its own layouts?

开发者 https://www.devze.com 2023-01-19 14:46 出处:网络
I wanna 开发者_开发问答have a different layout for the page not found 404 page. How can i set a different layout for that page?Savant from the IRC helped me out and he suggest in using beforeRender(){

I wanna 开发者_开发问答have a different layout for the page not found 404 page. How can i set a different layout for that page?


Savant from the IRC helped me out and he suggest in using beforeRender(){} in the app_controller

// Before Render
function beforeRender() {
    if($this->name == 'CakeError') {
        //$this->layout = 'error';
    }
}

CakeError is a catchAll for errors :D


In CakePHP 2.2.2 I changed the ExceptionRenderer in core.php with my own, like this:

app/Config/core.php:

Configure::write('Exception', array(
  'handler' => 'ErrorHandler::handleException',
  'renderer' => 'MyExceptionRenderer', // this is ExceptionRenderer by default
  'log' => true
));

app/Lib/Error/MyExceptionRenderer.php:

App::uses('ExceptionRenderer', 'Error');

class MyExceptionRenderer extends ExceptionRenderer {

  protected function _outputMessage($template) {
    $this->controller->layout = 'error';
    parent::_outputMessage($template);
  }

}


Just you need to make layout changes in your error400.ctp file under /app/View/Errors/error400.ctp

Open that file and set layout by

<?php $this->layout=''; //set your layout here ?>


better to create an error.php file in your app folder

class AppError extends ErrorHandler { 
    function error404($params) { 
            $this->controller->layout = 'error'; 
            parent::error404($params); 
    } 
}

so you can avoid the if-testing at EVERY page render that savants' solution introduces


My solution for CakePHP 2.3

Change the ExceptionRenderer in core.php to use your own renderer.

app/Config/core.php:

Configure::write('Exception', array(
  'handler' => 'ErrorHandler::handleException',
  'renderer' => 'MyExceptionRenderer',
  'log' => true
));

app/Lib/Error/MyExceptionRenderer.php:

 App::uses('ExceptionRenderer', 'Error');

 class MyExceptionRenderer extends ExceptionRenderer 
 {
    /**
     * Overrided, to always use a bare controller.
     * 
     * @param Exception $exception The exception to get a controller for.
     * @return Controller
     */
    protected function _getController($exception) {
        if (!$request = Router::getRequest(true)) {
            $request = new CakeRequest();
        }
        $response = new CakeResponse(array('charset' => Configure::read('App.encoding')));
        $controller = new Controller($request, $response);
        $controller->viewPath = 'Errors';
        $controller->layout = 'error';
        return $controller;
    }
 }

The advantage to this approach is that it ensures any exceptions thrown from AppController don't cause an endless loop when rendering the exception. Forces a basic rendering of the exception message every time.


This simplest way I know of is to create this function in your AppController:

function appError($method, $messages)
{
}

You can then do whatever you want with the error, display it however you like, or not display it at all, send an email etc.. (I'm not sure if this method if still valid.)

There is also an option of creating app_error.php in your app root, with class AppError extends ErrorHandler in it, which enables you to override all kinds of errors. But I haven't done this yet, so I can't tell you more about it.

See cake/libs/error.php and cake/libs/object.php and of course The Book for more info.

Edit: Forgot to mention, once you caught the error, there's nothing preventing you to - for example - store the error in session, redirect to your "error handling controller", and then display it in your controller however you want.

0

精彩评论

暂无评论...
验证码 换一张
取 消