Отримати ім'я контролера в шаблоні TWIG

Я навчаюся symfony2.3, і я отримую помилку, коли я намагаюся отримати ім'я контролера в шаблоні гілки.

Контролер:

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, але на обох версіях генерується та ж помилка.

6
Я хочу додати клас до деяких зв'язків на основі імені контролера.
додано Автор Hardeep Pandya, джерело
Але чому вам потрібна ця інформація?
додано Автор j0k, джерело

7 Відповіді

використовуйте цей рядок для відображення назви контролера в гілці:

{{ app.request.attributes.get("_controller") }}
20
додано
Цікаво, чому це не прийнята і найбільш проголошена відповідь, легка і чиста вбудована, в чому справа?!
додано Автор Bonswouar, джерело
tnx !! {{app.request.attributes.get ("_ route")}} для назви маршруту.
додано Автор Shay Altman, джерело

Багато місяців тому я мав таку ж проблему, як і ви, і "гугливши" я знайшов робочий код і пристосував його до своїх потреб. Ось і ми:

1 - We need to define a TWIG extension for that. We create the folder structure Your\OwnBundle\Twig\Extension if you haven't defined yet.

2 - Inside this folder we create the file ControllerActionExtension.php which code is:

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 - After that we need to specify the service for TWIG to be recognized:

services:
    your.own.twig.controller_action_extension:
        class: Your\OwnBundle\Twig\Extension\ControllerActionExtension
        calls:
            - [setRequest, ["@?request="]]
        tags:
            - { name: twig.extension }

4 - Cache clear to make sure everything is ok:

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

5 - And now, if I'm not forgetting anything, you will be able to access those 2 methods in a TWIG template: get_controller_name() and get_action_name()

6 - Examples:

You are in the {{ get_action_name() }} action of the {{ get_controller_name() }} controller.

This will output something like: You are in the index action of the default controller.

Також можна скористатися для перевірки:

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

І це все !! Сподіваюся, що допоміг вам, товариш :)

Edit: Take care about the clearing cache. If you don't use --no-warmup parameter maybe you will realize that nothing is shown in your templates. That's because this TWIG Extension uses the Request to extract the Controller and Action names. If you "warm up" the cache, the Request is not the same as a browser request, and the methods can return '' or null

16
додано
Мені потрібно отримати клас контролера з власного розширення гілки, використовуючи ваше рішення завжди отримую Ви запитали неіснуючу службу "sensio_distribution.webconfigurator"
додано Автор rkmax, джерело
Звичайно, розширення працює зараз, але мені потрібно додати нову функцію, і в цьому функціі мені потрібно використовувати запит
додано Автор rkmax, джерело
спасибі Дані, використовуючи документацію я знайшов мені потрібно використовувати область (я використовую symfony 2.4). я вирішу проблему з синтетичним сервісом :)
додано Автор rkmax, джерело
Ви оголосили це як послугу? (3-я точка моєї відповіді)
додано Автор Dani Sancas, джерело
Моя відповідь для Symfony 2.3, оскільки 2.4 запит у багатьох випадках обробляється по-іншому: symfony.com/blog/new-in-symfony-2-4-the-request-stack Я сподіваюся, що це допоможе вам. Якщо це не відбудеться, запитайте знову (або відкрийте запитання, щоб побачити весь ваш код і ціль, до якої ви хочете потрапити)
додано Автор Dani Sancas, джерело

Оскільки Symfony 3.x, запит на обслуговування замінюється на request_stack, а оголошення Twig Extension змінилося з Twig 1.12.

Я виправлю відповідь від Dani ( https://stackoverflow.com/a/17544023/3665477 ):

1 - We need to define a TWIG extension for that. We create the folder structure AppBundle\Twig\Extension if you haven't defined yet.

2 - Inside this folder we create the file ControllerActionExtension.php which code is:

<?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 - After that we need to specify the service for TWIG to be recognized:

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

4 - Cache clear to make sure everything is ok:

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

5 - And now, if I'm not forgetting anything, you will be able to access those 2 methods in a TWIG template: getControllerName() and getActionName()

6 - Examples:

Ви знаходитесь у дії {{getActionName ()}} контролера {{getControllerName ()}}.

Це виведе щось подібне: Ви знаходитесь в дії індексу контролера за замовчуванням.

Також можна скористатися для перевірки:

{% if getControllerName() == 'default' %}
Whatever
{% else %}
Blablabla
{% endif %}
5
додано

Я дійсно не бачу, ЧОМУ вам це буде потрібно Можливо, краще надсилати параметри до свого перегляду.

Але якщо ви дійсно потребуєте цього таким чином, ось рішення:

Ваша помилка випливає з другого методу get

request = app.request             //Request object
NULL    = request.get('_template')//Undefined attribute, default NULL
NULL.get('controller')            //Triggers error

If you want to get the controller called during the request you can access it via the key _controller of the request attribute

app.request.attribute.get('_controller')

Повернеться

Acme\AdminBundle\Controller\DefaultController::indexAction

Потім ви можете розібрати його так, як хочете.

Зауважте, що це не поверне екземпляр контролера, лише його ім'я та метод називається

1
додано
Код у вашому посиланні неправильний. Але ні, ви не можете отримати коротке ім'я (- контролер) класу контролера з вбудованої змінної Twig. Змінна app - це примірник Symfony Bundle, FrameworkBundle,
додано Автор Touki, джерело
Дякуємо за ваш інтерес до мого питання, але якщо є вбудована функціональність в symfony, то я повинен використовувати цей insteade розбору рядка див. Посилання я знайшов через веб ostedesign.com/…
додано Автор Hardeep Pandya, джерело

Контролер:

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

Дія:

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

насолоджуватися;)

1
додано

Він може змінюватися. Якщо ви використовуєте анотації в контролері, наприклад, @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] %}

If you're not using annotations then you can use the app.request.get('_template').get('_controller')

0
додано

Щоб отримати контролер - {{app.request.attributes.get ('_ controller')}} Щоб отримати дію - {{app.request.attributes.get ('_ template'). Get ('name')}}

Found at - http://forum.symfony-project.org/viewtopic.php?f=23&t=34083

0
додано