M
M
Mike Evstropov2016-06-29 22:49:53
symfony
Mike Evstropov, 2016-06-29 22:49:53

How to get route name in Twig extension (test)?

I'm trying to implement a test:

{% if 'homepage' is is_page %}текущая страница "homepage"{% endif %}

Created an extension in src/Site/AppBundle/Twig/TwigExtension.php and registered it as a service.
But how to get the name of the route in order to perform the check?
namespace Site\AppBundle\Twig;
class TwigExtension extends \Twig_Extension
{
    public function getTests()
    {
        return array(
            new \Twig_SimpleTest('is_page', array($this, 'isPageTest')),
        );
    }
    public function isPageTest($pageSlug = 'homepage')
    {
        return $pageSlug === 'homepage' ? true : false;
    }
    public function getName()
    {
        return 'twig_extension';
    }
}

services:
    site.twig_extension:
        class: Site\AppBundle\Twig\TwigExtension
        tags:
            - { name: twig.extension }

Answer the question

In order to leave comments, you need to log in

2 answer(s)
B
BoShurik, 2016-06-30
@Aroused

If we develop the idea from my answer to the question How to make an active menu? then:

namespace Site\AppBundle\Twig;

use Symfony\Component\HttpFoundation\Request;

class TwigExtension extends \Twig_Extension
{
    public function getTests()
    {
        return array(
            new \Twig_SimpleTest('match_route', array($this, 'matchRoute')),
        );
    }
    
    public function matchRoute(Request $request, $routeName, $routeParameters = array())
    {
        if (!$requestRouteName = $request->attributes->get('_route')) {
            return false;
        }

        if ($requestRouteName != $routeName) {
            return false;
        }

        if (empty($routeParameters)) {
            return true;
        }

        if (!$requestRouteParameters = $request->attributes->get('_route_params')) {
            return false;
        }

        $arrayIntersect = array_intersect_assoc($requestRouteParameters, $routeParameters);
        if (count($arrayIntersect) == count($routeParameters)) {
            return true;
        }

        return false;
    }

    public function getName()
    {
        return 'twig_extension';
    }
}

Use like this:
{% if app.request is match_route('homepage') %}текущая страница "homepage"{% endif %}
{% if app.request is match_route('entry', { 'name': 'info' }) %}текущая страница "info"{% endif %}

I
index0h, 2016-06-30
@index0h

If I understand correctly and you want to check if the route matches a specific action, then there is a simpler solution.

<?php

namespace MyVendor\MyApplication\AppBundle\Tests;

use KoKoKo\assert\Assert;
use KoKoKo\assert\exceptions\InvalidNotEmptyException;
use KoKoKo\assert\exceptions\InvalidNotObjectException;
use KoKoKo\assert\exceptions\InvalidStringException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;

trait ControllerTrait
{
    /**
     * @param Request $request
     * @param string  $controllerClass
     * @param string  $actionName
     * @throws InvalidNotEmptyException
     * @throws InvalidNotObjectException
     * @throws InvalidStringException
     */
    public function checkRoute(Request $request, $controllerClass, $actionName)
    {
        Assert::assert($controllerClass, 'controllerClass')->string()->notEmpty();
        Assert::assert($actionName, 'actionName')->string()->notEmpty();

        /** @noinspection PhpUndefinedMethodInspection */
        static::$kernel->getContainer()->get('router_listener')->onKernelRequest(
            new GetResponseEvent($this->getKernel(), $request, HttpKernelInterface::MASTER_REQUEST)
        );

        $parameters = $request->attributes->all();

        /** @noinspection PhpUndefinedMethodInspection */
        $this->assertInternalType('array', $parameters);
        /** @noinspection PhpUndefinedMethodInspection */
        $this->assertArrayHasKey('_controller', $parameters);
        /** @noinspection PhpUndefinedMethodInspection */
        $this->assertSame($controllerClass . '::' . $actionName, $parameters['_controller']);
    }
}

Used like this:
<?php

namespace MyVendor\MyApplication\AppBundle\Tests\Unit\Controller;

use MyVendor\MyApplication\AppBundle\Controller\MyController;
use MyVendor\MyApplication\AppBundle\Tests\ControllerTrait;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\HttpFoundation\Request;

class MyControllerTest extends KernelTestCase
{
    use ControllerTrait;

    public function testMyRoute()
    {
        self::bootKernel();

        $request = new Request();

        $request->server->set('REQUEST_URI', '/MyRoute');
        $request->setMethod('POST');

        $this->checkRoute($request, MyController::class, 'myRouteOfMyController');
    }
}

Here KoKoKo\assert\Assert is either for validating incoming arguments

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question