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

时间:2016-04-10 00:10:51

标签: php symfony

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

这很好用,但如果用户在网站的网站或管理部分,我希望有不同的页面。

有一种简单的方法吗? 谢谢你,迈克。

1 个答案:

答案 0 :(得分:5)

我认为最好的方法是overriding the default 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);
    }
}

然后配置twig.exception_controller

# app/config/services.yml
services:
    app.exception_controller:
        class: AppBundle\Controller\ExceptionController
        arguments: ['@twig', '%kernel.debug%']

# app/config/config.yml
twig:
    exception_controller:  app.exception_controller:showAction

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

  • 资源/的appbundle /视图/异常/
    • admin_error.html.twig
    • admin_error_404.html.twig
    • admin_error_500.html.twig
    • ...

更新

更简单的方法是在路由的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
然后你的控制器会变成这样:

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);
    }
}

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

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