2013-06-21 3 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)); 
    } 
} 

В моем шаблоне 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 

Я хочу, чтобы результат как "Default"

Я использую 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') 

Wil l return

Acme\AdminBundle\Controller\DefaultController::indexAction 

Вы можете разобрать его так, как хотите.

Обратите внимание, что это не будет возвращать экземпляр контроллера, только его имя и метод, называемый

+0

Спасибо за интерес к моему вопросу , но если в symfony есть встроенная функциональность, тогда я должен использовать эту настройку синтаксического анализа строки см. Ссылку, которую я нашел через веб-сайт http://ostedesign.com/get-controller-name-inside-symfony2 -twig-template –

+0

Код в вашей ссылке неправильный. Но нет, вы не можете получить ** shortname ** (- Controller) класса контроллера из встроенной переменной Twig. Переменная 'app' представляет собой экземпляр' Symfony \ Bundle \ FrameworkBundle \ Templating \ GlobalVariables', который не выставляет его контейнер – Touki

-1

Контроллер:

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

Действие:

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

наслаждаться;)

16

Много месяцев назад у меня было то же самое как вы, и «googling», я нашел рабочий код, и я адаптировал его к моим потребностям. Здесь мы идем:

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 - И теперь, если я ничего не пропущено, вы сможете получить доступ к этим 2 метода в шаблоне 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 Extension использует запрос для извлечения имен Controller и Action. Если вы «разогреть» кэш, то запрос не то же самое как запрос браузера и методы могут возвращать '' или null

+0

Мне нужно получить класс контроллера из пользовательского расширения ветки, используя ваше решение, всегда получаю 'Вы запросили не -existent service "sensio_distribution.webconfigurator" ' – rkmax

+0

Вы объявили его как услугу? (3-я точка моего ответа) –

+0

Конечно, расширение работает сейчас, но мне нужно добавить новую функцию, и в этой функции мне нужно использовать Request – rkmax

18

использовать эту линию, чтобы отобразить имя контроллера в веточке:

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

tnx !! '{{app.request.attributes.get (" _ route ")}}' для имени маршрута. –

+0

Интересно, почему это не принятый и самый проголосовавший ответ, простой и чистый встроенный, в чем дело?! – Bonswouar

0

Может варьироваться. Если вы используете аннотации в контроллере, например. @Template("AcmeDemoBundle:Default:index"), пытающийся получить доступ к app.request.get('_template') в вашем шаблоне Twig, вернет строку, например. "AcmeDemoBundle: По умолчанию: индекс". Таким образом, вы, возможно, потребуется доступ к нему, как это:

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

Если вы не используете аннотации, то вы можете использовать app.request.get('_template').get('_controller')

5

Так как Symfony 3.x, запрос на обслуживание заменяется request_stack и Twig Extension с тех пор, как Twig 1.12.

Я исправит ответ Дани (https://stackoverflow.com/a/17544023/3665477):

1 - Нам необходимо определить расширение TWIG для этого. Мы создаем структуру папок 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 - Cache ясно, чтобы убедиться, что все в порядке:

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

5 - И теперь, если я ничего не пропущено, вы сможете получить доступ к этим 2 метода в шаблоне TWIG: getControllerName() и getActionName()

6 - Примеры:

Вы в {{getActionName()}} действие {{getControllerName)} (} контроллера.

Это выведет что-то вроде: вы находитесь в действии индекса контроллера по умолчанию.

Вы можете также использовать для проверки:

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