使用.html.php模板在symfony 2.0中自定义错误页面

时间:2014-03-28 04:55:06

标签: symfony

我正在使用带有php模板的symfony 2.0版本。如何使用php模板创建自定义错误页面?我有symfony的基本知识,请帮助我

2 个答案:

答案 0 :(得分:2)

问题:Symfony只创建了一个Twig ExceptionController。这是设计的:你可以在这里看到他们选择只支持这个组件的枝条,所以不要打扰他们开票:https://github.com/symfony/symfony/issues/7285

解决方案:您将创建自己的ExceptionController。原始位于Symfony \ Bundle \ TwigBundle \ Controller \ ExceptionController。我选择不延长原件,因为我没有使用它来保证连接。

以下是我最终得到的控制器。它支持首先查找PHP错误模板,如果找不到它,它将故障转移到使用内置的twig。

namespace Rate\CommonBundle\Controller;

use Rate\CommonBundle\Entity\AjaxResponse;
use Symfony\Bundle\FrameworkBundle\Templating\TemplateReference;
use Symfony\Component\HttpKernel\Exception\FlattenException;
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

/**
 * NOTE: when overriding twig exception/error templates in the app space, you MUST CLEAR CACHE AFTER ADDING A NEW ONE
 *
 * This file is specified to be used in parameters.yml
 *
 * For "non debug" environments (production), error templates will be used.  For dev environments, exception
 * templates are used
 */
class ExceptionController
{
    /**
     * @var \Symfony\Bundle\FrameworkBundle\Templating\DelegatingEngine
     */
    protected $templating;
    /**
     * @var \Twig_Environment
     */
    protected $twig;
    /**
     * @var bool
     */
    protected $debug;

    public function __construct($templating, \Twig_Environment $twig, $debug)
    {
        $this->templating = $templating;
        $this->twig = $twig;
        $this->debug = $debug;
    }

    /**
     * Converts an Exception to a Response.
     *
     * @param Request              $request   The request
     * @param FlattenException     $exception A FlattenException instance
     * @param DebugLoggerInterface $logger    A DebugLoggerInterface instance
     * @param string               $_format   The format to use for rendering (html, xml, ...)
     *
     * @return Response
     *
     * @throws \InvalidArgumentException When the exception template does not exist
     */
    public function showAction(Request $request, FlattenException $exception, DebugLoggerInterface $logger = null, $_format = 'html')
    {
        $currentContent = $this->getAndCleanOutputBuffering($request->headers->get('X-Php-Ob-Level', -1));
        $code = $exception->getStatusCode();
        $template = $this->findTemplate($request, $_format, $code, $this->debug);

        if ($template->get('engine') == 'php') {
            $engine =& $this->templating;
        } else {
            $engine =& $this->twig;
        }

        return new Response($engine->render(
            $template,
            array(
                'status_code'    => $code,
                'status_text'    => isset(Response::$statusTexts[$code]) ? Response::$statusTexts[$code] : '',
                'exception'      => $exception,
                'logger'         => $logger,
                'currentContent' => $currentContent,
            )
        ));
    }

    /**
     * @param int     $startObLevel
     *
     * @return string
     */
    protected function getAndCleanOutputBuffering($startObLevel)
    {
        if (ob_get_level() <= $startObLevel) {
            return '';
        }

        Response::closeOutputBuffers($startObLevel + 1, true);

        return ob_get_clean();
    }

    /**
     * @param Request $request
     * @param string  $format
     * @param int     $code       An HTTP response status code
     * @param bool    $debug
     *
     * @return TemplateReference
     */
    protected function findTemplate(Request $request, $format, $code, $debug)
    {
        $name = $debug ? 'exception' : 'error';
        if ($debug && 'html' == $format) {
            $name = 'exception_full';
        }

        // when not in debug, try to find a template for the specific HTTP status code and format
        //if (!$debug) {
            $template = new TemplateReference('RateCommonBundle', 'Exception', $name.$code, $format, 'php');
            if ($this->templating->exists($template)) {
                return $template;
            }
        //}

        // try to find a template for the given format
        $template = new TemplateReference('RateCommonBundle', 'Exception', $name, $format, 'php');
        if ($this->templating->exists($template)) {
            return $template;
        }

        // default to a generic HTML exception
        $request->setRequestFormat('html');
        // Check if we have a custom one
        $template = new TemplateReference('RateCommonBundle', 'Exception', $name, 'html', 'php');
        if ($this->templating->exists($template)) {
            return $template;
        }

        // fallback to built-in twig templates
        return new TemplateReference('TwigBundle', 'Exception', $name, 'html', 'twig');
    }
}

用法:此控制器以及我的错误页面存在于我的应用中的CommonBundle中。你可以将它们放在你想要的任何包中,但你必须调整ExceptionController::findTemplate函数,以便查看正确的包。

注意,TemplateReference()的构造函数中的第二个参数是包含Resources / views的子文件夹。所以我的错误模板位于Rate\CommonBundle\Resources\views\Exception

Symfony DI :Symfony在处理异常时使用twig.controller.exception服务(请参阅此处引用:http://symfony.com/doc/current/reference/configuration/twig.html#config-twig-exception-controller),因此您必须在config.yml

twig.controller.exception:
    class: %twig.controller.exception.class%
    arguments: [ "@templating", "@twig", %kernel.debug% ]

你可以看到我正在注入PHP模板引擎和twig引擎。

您还必须在参数中指定完整的类路径:

twig.controller.exception.class: Rate\CommonBundle\Controller\ExceptionController

应该这样做。我希望这适合你。

答案 1 :(得分:1)

来自上面的链接:

要覆盖显示给最终用户的默认错误模板,请创建位于app / Resources / TwigBundle / views / Exception / error.html.twig的新模板:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>An Error Occurred: {{ status_text }}</title>
</head>
<body>
    <h1>Oops! An Error Occurred</h1>
    <h2>The server returned a "{{ status_code }} {{ status_text }}".</h2>
</body>
</html>

您还可以根据HTTP状态代码自定义特定的错误模板。例如,创建app / Resources / TwigBundle / views / Exception / error404.html.twig模板以显示404(找不到页面)错误的特殊页面。

修改 我想如果你想把它作为一个php模板,你在配置中有正确的设置

# app/config/config.yml
framework:
    # ...
    templating:
        engines: ['twig', 'php']

您应该只能将扩展名更改为.html.php,它应该可以正常工作。 (并替换php内容的枝条内容)

修改 请尝试以下app/Resources/TwigBundle/views/Exception/error.html.php

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>An Error Occurred: <?php echo $status_text ?></title>
</head>
<body>
    <h1>Oops! An Error Occurred</h1>
    <h2>The server returned a "<?php echo $status_code ?> <?php echo $status_text ?>".</h2>
</body>
</html>

请尝试并报告。 THX