我正在使用带有php模板的symfony 2.0版本。如何使用php模板创建自定义错误页面?我有symfony的基本知识,请帮助我
答案 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