1

I am developing an application which uses themes for layouts, and I need to use custom themes for all the error pages too.

Looking at the docs, I see that I can change layout fairly easily by using

$this->layout = 'mylayout';

in the error page itself, but I need to change the theme too. I have tried with

$this->theme = 'mytheme';

but the error page is still using the default theme, so I guess this is not the right way to set it.

What is the correct way to set a theme for error pages?

ndm
  • 59,784
  • 9
  • 71
  • 110
ToX 82
  • 1,064
  • 12
  • 35

1 Answers1

3

Themes are easiest to be set via the Controller.beforeRender event, or for earlier CakePHP versions, via the Controller::$theme property.

The default exception renderer uses a new controller instance for handling errors, therefore you can for example

Create a custom error controller and add a listener/callback

One option would be to create a custom error controller where you can set the theme as you would in a regular controller. By default CakePHP will use \App\Controller\ErrorController if it exists, so all you'd need to do would be to create the controller.

src/Controller/ErrorController.php

namespace App\Controller;

use Cake\Controller\Controller;
use Cake\Event\Event;

class ErrorController extends Controller
{
    public function beforeRender(Event $event)
    {
        $this->viewBuilder()->theme('ErrorThemeName');
    }
}

Done, all exceptions should now use the ErrorThemeName theme.

See also

Create a custom exception renderer and add a listener to the controller

You could also create a custom/extended exception renderer, and override ExceptionRenderer::_getController(), and add a proper listener for the Controller.beforeRender where you can set the theme.

src/Error/AppExceptionRenderer.php

namespace App\Error;

use Cake\Error\ExceptionRenderer;
use Cake\Event\Event;

class AppExceptionRenderer extends ExceptionRenderer
{
    protected function _getController()
    {
        $controller = parent::_getController();
        $controller->eventManager()->on('Controller.beforeRender', function (Event $event) {
            $event->subject()->viewBuilder()->theme('ErrorThemeName');
        });
        return $controller;
    }
}

config/app.php

// ...
'Error' => [
    'exceptionRenderer' => '\App\Error\AppExceptionRenderer',
    // ...
],
// ...

See also

Cookbook > Error & Exception Handling > Using the exceptionRenderer Option of the Default Handler

ndm
  • 59,784
  • 9
  • 71
  • 110
  • ndm, you are the best! It worked perfectly. I was trying to do the same through the `AppController`, but it wasn't working... thank you! – ToX 82 Aug 12 '16 at 16:57
  • I think that the `ErrorController` thing should go in the documentation, it is a simple and useful tip for someone in my situation... – ToX 82 Aug 12 '16 at 17:17