【发布时间】:2013-04-13 01:05:22
【问题描述】:
我只想显示 /sitemap 页面,而不是错误页面 / 404。当然我不想要重定向,我仍然想要设置 404 HTTP 响应头。
这可能吗?我只能看到如何在 Twig 中设置模板。
我绝对不想要重定向。
【问题讨论】:
标签: symfony
我只想显示 /sitemap 页面,而不是错误页面 / 404。当然我不想要重定向,我仍然想要设置 404 HTTP 响应头。
这可能吗?我只能看到如何在 Twig 中设置模板。
我绝对不想要重定向。
【问题讨论】:
标签: symfony
如the Symfony Cookbook 所示,您可以通过两种方式覆盖错误页面:
如果您只想在 404 (HttpNotFoundException) 异常中显示 /sitemap 路由,您可以通过在 app/Resources/TwigBundle/views/Exception/error404.html.twig 中创建新模板来覆盖 Twig 异常模板。
说明书中未显示的另一种方法是使用事件侦听器。当内核遇到异常时,将调度kernel.exception 事件。默认情况下,这个异常会被 Twig 提供的异常监听捕获。您可以create your own event listener 监听kernel.exception 事件并呈现页面:
<?php
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpFoundation\Response;
public function onKernelException(GetResponseForExceptionEvent $event)
{
if ($event->getException() instanceof NotFoundHttpException) {
$response = $this->templating->renderResponse(/* sitemap */);
$event->setResponse($response)
}
}
(我没有测试过这段代码,所以你应该自己尝试一下!当然,你必须自己将模板服务注入到事件监听器中)。
【讨论】:
templating 服务注入事件侦听器。
Controller 类的 the source 以查看用于在控制器中呈现模板并将这些服务注入事件侦听器的内容。
我有一个由几个 Symfony3 包组成的简单 Web 应用程序,所有这些包都扩展了 BaseController。我也有一个 AdminBundle。为了显示每个不存在的 url 的给定页面,我破解了(并简化了)原始 ExceptionController.php(来自 TwigBundle):
<?php
namespace MyApp\AdminBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use MyApp\Controller\BaseController;
use Symfony\Component\Debug\Exception\FlattenException;
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
class ExceptionController extends BaseController
{
/**
* Converts an Exception to a Response.
*
* @param Request $request The request
* @param FlattenException $exception A FlattenException instance
* @param DebugLoggerInterface $logger A DebugLoggerInterface instance
*
* @return Response
* @throws \InvalidArgumentException When the exception template does not exist
*/
public function showAction(Request $request, FlattenException $exception, DebugLoggerInterface $logger = null)
{
$currentContent = $this->getAndCleanOutputBuffering($request->headers->get('X-Php-Ob-Level', -1));
$code = $exception->getStatusCode();
return $this->render('MyappAdminBundle:Admin:error.html.twig',
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();
}
}
我根据自己的喜好定义我的错误模板。
我需要在 config.yml 中添加以下行
twig:
exception_controller: MyappAdminBundle:Exception:show
ps 我确信我的代码可以改进,但它工作正常。
【讨论】:
最简单的方法是创建这个文件:
/app/Resources/TwigBundle/views/Exception/error404.html.twig
/templates/bundles/TwigBundle/Exception/error404.html.twig
...并将这一行复制到其中:
{{ render(controller('App\\Controller\\HomepageController::index')) }}
就是这样。这将显示带有 404 状态代码的主页。它只适用于prod 环境(清除缓存!),因为在dev 和test Symfony 总是显示其异常页面。
参考资料:
【讨论】: