我正在学习symfony2.3,当我尝试在twig模板中获取控制器名称时出现错误。
控制器:
namespace Acme\AdminBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
class DefaultController extends Controller
{
public function indexAction($name)
{
return $this->render('AcmeAdminBundle:Default:index.html.twig', array('name' => $name));
}
}
在我的TWIG模板中:
{% extends '::base.html.twig' %}
{% block body %}
{{ app.request.get('_template').get('controller') }}
Hello {{ name }}!!!
{% endblock %}
输出:
Impossible to invoke a method ("get") on a NULL variable ("") in AcmeAdminBundle:Default:index.html.twig at line 3
我希望输出为“默认”
我正在使用symfony 2.3,我也尝试过symfony 2.1,但两个版本都会产生相同的错误。
答案 0 :(得分:22)
使用此行在树枝中显示控制器名称:
{{ app.request.attributes.get("_controller") }}
答案 1 :(得分:16)
很多个月前,我遇到了和你一样的问题,并且“谷歌搜索”我发现了一个正常工作的代码,我已经将它改编成了我的必需品。我们走了:
1 - 我们需要为此定义一个TWIG扩展名。如果您尚未定义,我们将创建文件夹结构 Your \ OwnBundle \ Twig \ Extension 。
2 - 在此文件夹中,我们创建了文件 ControllerActionExtension.php ,代码为:
namespace Your\OwnBundle\Twig\Extension;
use Symfony\Component\HttpFoundation\Request;
/**
* A TWIG Extension which allows to show Controller and Action name in a TWIG view.
*
* The Controller/Action name will be shown in lowercase. For example: 'default' or 'index'
*
*/
class ControllerActionExtension extends \Twig_Extension
{
/**
* @var Request
*/
protected $request;
/**
* @var \Twig_Environment
*/
protected $environment;
public function setRequest(Request $request = null)
{
$this->request = $request;
}
public function initRuntime(\Twig_Environment $environment)
{
$this->environment = $environment;
}
public function getFunctions()
{
return array(
'get_controller_name' => new \Twig_Function_Method($this, 'getControllerName'),
'get_action_name' => new \Twig_Function_Method($this, 'getActionName'),
);
}
/**
* Get current controller name
*/
public function getControllerName()
{
if(null !== $this->request)
{
$pattern = "#Controller\\\([a-zA-Z]*)Controller#";
$matches = array();
preg_match($pattern, $this->request->get('_controller'), $matches);
return strtolower($matches[1]);
}
}
/**
* Get current action name
*/
public function getActionName()
{
if(null !== $this->request)
{
$pattern = "#::([a-zA-Z]*)Action#";
$matches = array();
preg_match($pattern, $this->request->get('_controller'), $matches);
return $matches[1];
}
}
public function getName()
{
return 'your_own_controller_action_twig_extension';
}
}
3 - 之后我们需要指定要识别的TWIG服务:
services:
your.own.twig.controller_action_extension:
class: Your\OwnBundle\Twig\Extension\ControllerActionExtension
calls:
- [setRequest, ["@?request="]]
tags:
- { name: twig.extension }
4 - 缓存清除以确保一切正常:
php app/console cache:clear --no-warmup
5 - 现在,如果我没有忘记任何内容,您将能够在TWIG模板中访问这两种方法:get_controller_name()
和get_action_name()
6 - 示例:
You are in the {{ get_action_name() }} action of the {{ get_controller_name() }} controller.
这将输出如下内容:您处于默认控制器的索引操作中。
您还可以使用以检查:
{% if get_controller_name() == 'default' %}
Whatever
{% else %}
Blablabla
{% endif %}
这就是全部!!我希望我能帮助你,交配:)。
编辑:注意清算缓存。如果您不使用--no-warmup
参数,您可能会发现模板中没有显示任何内容。那是因为这个TWIG扩展使用Request来提取Controller和Action名称。如果您“预热”缓存,请求与浏览器请求不同,方法可以返回''
或null
答案 2 :(得分:5)
自Symfony 3.x起,服务请求被request_stack取代,Twig扩展声明自Twig 1.12以来发生了变化。
我会更正Dani(https://stackoverflow.com/a/17544023/3665477)的答案:
1 - 我们需要为此定义一个TWIG扩展名。如果您还没有定义,我们会创建文件夹结构 AppBundle \ Twig \ Extension 。
2 - 在此文件夹中,我们创建了文件 ControllerActionExtension.php ,代码为:
my-task
3 - 之后我们需要指定要识别的TWIG服务:
<?php
namespace AppBundle\Twig\Extension;
use Symfony\Component\HttpFoundation\RequestStack;
class ControllerActionExtension extends \Twig_Extension
{
/** @var RequestStack */
protected $requestStack;
public function __construct(RequestStack $requestStack)
{
$this->requestStack = $requestStack;
}
public function getFunctions()
{
return [
new \Twig_SimpleFunction('getControllerName', [$this, 'getControllerName']),
new \Twig_SimpleFunction('getActionName', [$this, 'getActionName'])
];
}
/**
* Get current controller name
*
* @return string
*/
public function getControllerName()
{
$request = $this->requestStack->getCurrentRequest();
if (null !== $request) {
$pattern = "#Controller\\\([a-zA-Z]*)Controller#";
$matches = [];
preg_match($pattern, $request->get('_controller'), $matches);
return strtolower($matches[1]);
}
}
/**
* Get current action name
*
* @return string
*/
public function getActionName()
{
$request = $this->requestStack->getCurrentRequest();
if (null !== $request) {
$pattern = "#::([a-zA-Z]*)Action#";
$matches = [];
preg_match($pattern, $request->get('_controller'), $matches);
return $matches[1];
}
}
public function getName()
{
return 'controller_action_twig_extension';
}
}
4 - 缓存清除以确保一切正常:
app.twig.controller_action_extension:
class: AppBundle\Twig\Extension\ControllerActionExtension
arguments: [ '@request_stack' ]
tags:
- { name: twig.extension }
5 - 现在,如果我没有忘记任何内容,您将能够在TWIG模板中访问这两个方法: getControllerName()和 getActionName()
6 - 示例:
您在{{getControllerName()}}控制器的{{getActionName()}}操作中。
这将输出如下内容:您处于默认控制器的索引操作中。
您还可以使用以检查:
php bin/console cache:clear --no-warmup
答案 3 :(得分:1)
我真的不明白你为什么需要这个 您最好将参数发送到视图中。
但如果你真的需要这种方式,这是一个解决方案:
您的错误来自第二个get
方法
request = app.request // Request object
NULL = request.get('_template') // Undefined attribute, default NULL
NULL.get('controller') // Triggers error
如果您想在请求期间调用控制器,可以通过请求属性
的密钥_controller
访问它
app.request.attribute.get('_controller')
将返回
Acme\AdminBundle\Controller\DefaultController::indexAction
然后您可以按照自己的方式解析它。
请注意,这不会返回控制器实例,只会返回其名称和方法
答案 4 :(得分:0)
获取控制器 - {{app.request.attributes.get('_ controller')}} 要获取操作 - {{app.request.attributes.get('_ template')。get('name')}}
找到 - http://forum.symfony-project.org/viewtopic.php?f=23&t=34083
答案 5 :(得分:0)
它可以变化。如果您在控制器中使用注释,例如@Template("AcmeDemoBundle:Default:index")
,尝试访问Twig模板中的app.request.get('_template')
将返回一个字符串,例如“AcmeDemoBundle:默认:指数”。所以你可能需要像这样访问它:
{% set _template = app.request.get('_template')|split(':') %}
{% set controller = _template[1] %}
{% set bundle = _template[0] %}
如果您没有使用注释,则可以使用app.request.get('_template').get('_controller')
答案 6 :(得分:-1)
控制器:
{{ app.request.attributes.get('_template').get('controller') }}
动作:
{{ app.request.attributes.get('_template').get('name') }}
享受;)