我想更改@Template
注释的默认行为,该注释会自动呈现名为控制器操作的模板。
所以在ArticleController.php
/**
* @Route("/new", name="article_new")
* @Method("GET")
* @Template()
*/
public function newAction()
{
// ...
return array();
}
会呈现Article/new.html.twig
。
我想将其更改为引用调用操作的路径的名称,这样您就可以为每个呈现不同模板的操作创建多个路径。
这是我目前的做法(没有@Template
):
/**
* @Route("/new", name="article_new")
* @Route("/new_ajax", name="article_new_ajax")
* @Method("GET")
*/
public function newAction()
{
// ...
$request = $this->getRequest();
$route = $request->attributes->get('_route');
$template = 'AcmeDemoBundle:' . $route . '.html.twig';
return $this->render($template, array(
// ...
));
}
我现在想知道是否有办法改变@Template
的行为来做到这一点。有没有办法自定义注释或只是一些方法,使其更加自动化?
有什么想法吗?
答案 0 :(得分:1)
我现在已经找到了使用kernelView事件的解决方案。这与@Template
注释不同。只要控制器操作没有返回响应对象,就会触发kernelView事件。
(此解决方案基于Symfony 2.4)
事件监听器服务:
services:
kernel.listener.route_view:
class: Acme\DemoBundle\Templating\RouteView
arguments: ["@request_stack", "@templating"]
tags:
- { name: kernel.event_listener, event: kernel.view }
事件监听器类:
namespace Acme\DemoBundle\Templating;
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
class RouteView
{
protected $controller;
protected $route;
protected $templating;
function __construct(RequestStack $requestStack, $templating)
{
$this->controller = $requestStack->getCurrentRequest()->attributes->get('_controller');
$this->route = $requestStack->getCurrentRequest()->attributes->get('_route');
$this->templating = $templating;
}
public function onKernelView(GetResponseForControllerResultEvent $event)
{
$controllerAction = substr($this->controller, strrpos($this->controller, '\\') + 1);
$controller = str_replace('Controller', '', substr($controllerAction, 0, strpos($controllerAction, '::')));
$template = 'AcmeDemoBundle:' . $controller . ':' . str_replace(strtolower($controller) . '_', '', $this->route) . '.html.twig';
$response = $this->templating->renderResponse($template, $event->getControllerResult());
$event->setResponse($response);
}
}
现在控制器的行为如下:
/**
* @Route("/new", name="article_new") -> Article:new.html.twig
* @Route("/new_ajax", name="article_new_ajax") -> Article:new_ajax.html.twig
* @Method("GET")
*/
public function newAction()
{
// ...
return array();
}
答案 1 :(得分:0)
如果在类级别使用@Template
注释,则FOSRestBundle包含与@View
类似的功能,但在my pull request以后的类级别。
如果您希望模板文件名反映操作 - 名称而不是路径名称(而不是问题中要求的内容),则此功能非常有用。
渲染的模板将是......
<controller-name>/<action-name>.html.twig
...用于HTML视图。
示例:AcmeBundle\Controller\PersonController::create()
将呈现
AcmeBundle/Resources/views/Person/create.html.twig
在PR之前,你必须注释每个方法。
注释方法仍然可以覆盖模板,模板变量和状态代码。
示例:强>
/**
* @FOSRest\View(templateVar="testdata", statusCode=201)
*/
class PersonController implements ClassResourceInterface
{
public function newAction()
{
return $this->formHandler->createForm();
// template: Person/new.html.twig
// template variable is 'form'
// http status: 201
}
public function helloAction()
{
return "hello";
// template: Person/hello.html.twig
// template variable 'testdata'
// http status: 201
}
/**
* @FOSRest\View("AnotherBundle:Person:get", templatevar="person")
*/
public function getAction(Person $person)
{
return $person;
// template: AnotherBundle:Person:get
// template variable is 'person'
// http status: 201
}
/**
* @FOSRest\View("AnotherBundle:Person:overview", templatevar="persons", statusCode=200)
*/
public function cgetAction()
{
return $this->personManager->findAll();
// template: AnotherBundle:Person:overview
// template variable is 'persons'
// http status: 200
}
// ...