Symfony - 公共和管理部分的不同错误页面

Mik*_*ike 2 php symfony

我一直在关注http://symfony.com/doc/current/cookbook/controller/error_pages.html上的提示,并在Resources/TwigBundle/views/Exceptions中创建了新模板error500.html.twig.

这工作正常,但如果用户在网站的网站或管理部分,我希望有不同的页面.

有一个简单的方法吗?谢谢你,迈克.

Fed*_*kun 5

我认为最好的方法是覆盖默认的ExceptionController.只需扩展它,并覆盖该findTemplate方法.检查请求的属性是否存在_route_controller设置,并对其执行操作.

namespace AppBundle\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\TwigBundle\Controller\ExceptionController as BaseExceptionController;

class ExceptionController extends BaseExceptionController
{
    protected function findTemplate(Request $request, $format, $code, $showException)
    {
        $routeName = $request->attributes->get('_route');

        // You can inject these routes in the construct of the controller
        // so that you can manage them from the configuration file instead of hardcode them here
        $routesAdminSection = ['admin', 'admin_ban', 'admin_list'];

        // This is a poor implementation with in_array.
        // You can implement more advanced options using regex 
        // so that if you pass "^admin" you can match all the routes that starts with admin.

        // If the route name match, then we want use a different template: admin_error_CODE.FORMAT.twig
        // example: admin_error_404.html.twig
        if (!$showException && in_array($routeName, $routesAdminSection, true)) {
            $template = sprintf('@AppBundle/Exception/admin_error_%s.%s.twig', $code, format);
            if ($this->templateExists($template)) {
                return $template;
            }

            // What you want to do if the template doesn't exist?
            // Just use a generic HTML template: admin_error.html.twig
            $request->setRequestFormat('html');
            return sprintf('@AppBundle/Exception/admin_error.html.twig');
        }

        // Use the default findTemplate method
        return parent::findTemplate($request, $format, $code, $showException);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后配置twig.exception_controller:

# app/config/services.yml
services:
    app.exception_controller:
        class: AppBundle\Controller\ExceptionController
        arguments: ['@twig', '%kernel.debug%']
Run Code Online (Sandbox Code Playgroud)

# app/config/config.yml
twig:
    exception_controller:  app.exception_controller:showAction
Run Code Online (Sandbox Code Playgroud)

然后,您可以以相同的方式覆盖模板:

  • 资源/的appbundle /视图/例外/
    • admin_error.html.twig
    • admin_error_404.html.twig
    • admin_error_500.html.twig
    • ...

UPDATE

更简单的方法是defaults在路径集合中指定网站的部分.例:

# app/config/routing.yml
home:
    path:      /
    defaults:
        _controller: AppBundle:Main:index
        section:     web
blog:
    path:      /blog/{page}
    defaults:
        _controller: AppBundle:Main:blog
        section:     web
dashboard:
    path:      /admin
    defaults:
        _controller: AppBundle:Admin:dashboard
        section:     admin
stats:
    path:      /admin/stats
    defaults:
        _controller: AppBundle:Admin:stats
        section:     admin
Run Code Online (Sandbox Code Playgroud)

然后你的控制器变成这样:

namespace AppBundle\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\TwigBundle\Controller\ExceptionController as BaseExceptionController;

class ExceptionController extends BaseExceptionController
{
    protected function findTemplate(Request $request, $format, $code, $showException)
    {
        $section = $request->attributes->get('section');
        $template = sprintf('@AppBundle/Exception/%s_error_%s.%s.twig', $section, $code, format);
        if ($this->templateExists($template)) {
            return $template;
        }

        return parent::findTemplate($request, $format, $code, $showException);
    }
}
Run Code Online (Sandbox Code Playgroud)

twig.exception_controller以与上述相同的方式配置.现在,您只需为每个部分,代码和格式定义模板.

  • web_error_404.html.twig
  • web_error_500.html.twig
  • admin_error_404.html.twig
  • admin_error_500.html.twig
  • 等等...