2013-06-21 44 views
6

我正在學習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)); 
    } 
} 

在我的嫩枝模板:

{% 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

但是,你爲什麼需要這些信息? – j0k

+0

我想添加類到一些鏈接的基礎上的控制器名稱。 –

回答

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') 

威爾l返回

Acme\AdminBundle\Controller\DefaultController::indexAction 

然後,您可以按照自己想要的方式進行解析。

注意,這將不會返回控制器實例,只有它的名字和方法叫做

+0

感謝您對我的問題 的關注,但是如果symfony中有內置功能,那麼我應該使用解析字符串的內聯,參見我在網上找到的鏈接http://ostedesign.com/get-controller-name-inside-symfony2 -twig-template –

+0

鏈接中的代碼錯誤。但是,不,你不能從內置的Twig變量中獲得控制器類的** shortname **( - Controller)。 'app'變量是一個'Symfony \ Bundle \ FrameworkBundle \ Templating \ GlobalVariables'實例,它不公開其容器 – Touki

-1

控制器:

{{ app.request.attributes.get('_template').get('controller') }} 

操作:

{{ app.request.attributes.get('_template').get('name') }} 

享受;)

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 -之後,我們需要指定服務嫩枝被認可:

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 -現在,如果我不忘記什麼,你將能夠訪問在一根樹枝模板的2種方法: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擴展使用請求來提取控制器和操作名稱。如果你「熱身」的高速緩存,該請求是不一樣的瀏覽器請求,並且方法可以返回''null

+0

我需要從一個自定義的分支擴展中獲取控制器類,使用你的解決方案總是我得到'你已經請求了一個非現有服務「sensio_distribution.webconfigurator」 – rkmax

+0

您是否將其聲明爲服務? (我的答案的第三點) –

+0

當然,擴展工作現在,但我需要添加一個新的功能,在這個功能我需要使用請求 – rkmax

18

使用這條線,以顯示樹枝控制器名稱:

{{ app.request.attributes.get("_controller") }} 
+1

tnx !! '{{app.request.attributes.get(「_ route」)}}'用於路由名稱。 –

+0

我想知道爲什麼這不是公認的和最受投票的答案,簡單和乾淨的內置,有什麼事嗎?! – Bonswouar

0

它可以變化。如果您在控制器中使用註釋,例如@Template("AcmeDemoBundle:Default:index"),試圖訪問您的Twig模板中的app.request.get('_template')將返回一個字符串,例如「AcmeDemoBundle:默認:指數」。所以,你可能需要訪問它是這樣的:如果你不使用註釋,那麼你可以使用app.request.get('_template').get('_controller')

5

由於Symfony的3.x的

{% set _template = app.request.get('_template')|split(':') %} 
{% set controller = _template[1] %} 
{% set bundle = _template[0] %} 

,服務請求被request_stack替換,嫩枝擴展聲明自Twig 1.12以來發生了變化。

我會改正達尼(https://stackoverflow.com/a/17544023/3665477)的答案:

1 -我們需要定義爲一根樹枝延伸。如果您尚未定義,我們將創建文件夾結構AppBundle \ Twig \ Extension

2 -此文件夾中,我們創建文件ControllerActionExtension.php它的代碼是:

<?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'; 
    } 
} 

3 -之後,我們需要指定服務TWIG得到認可:

app.twig.controller_action_extension: 
    class: AppBundle\Twig\Extension\ControllerActionExtension 
    arguments: [ '@request_stack' ] 
    tags: 
     - { name: twig.extension } 

4 -緩存清除以確保一切正常:

php bin/console cache:clear --no-warmup 

5 -而現在,如果我不忘記什麼,你將能夠訪問在一根樹枝模板的2種方法:getControllerName()getActionName()

6 -示例:

您正在{{getControllerName()}}控制器的{{getActionName()}}動作中。

這將輸出如下內容:您處於默認控制器的索引操作中。

你也可以用它來檢查:

{% if getControllerName() == 'default' %} 
Whatever 
{% else %} 
Blablabla 
{% endif %}