-1

I'm trying to change the output of {{ url('app_route_name') }} or {{ path('app_route_name') }}. Normally the output might be /app/route/name I'm wanting to modify the twig output only.

My first attempt was decorating UrlGenerator->generate, but changing $name also changed the controller called. I just want to change the final output.

Here is the code I'm currently trying. The error exception I'm getting is:

Unknown "path" function. Did you mean "logout_path", "relative_path", "impersonation_exit_path"?

    App\Service\TwigUrlDecorator:
        decorates: 'twig.extension.routing'
        arguments: ['@.inner']
        public: false
// src/Service/TwigUrlDecorator.php

namespace App\Service;

use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Twig\Extension\AbstractExtension;
use Symfony\Bridge\Twig\Extension\RoutingExtension;

class TwigUrlDecorator extends AbstractExtension
{
    private $generator;
    private $router;

    public function __construct(RoutingExtension $router, UrlGeneratorInterface $generator)
    {
        $this->router = $router;
        $this->generator = $generator;
    }

    public function getPath(string $name, array $parameters = [], bool $relative = false): string
    {
        return $this->generator->generate($name, $parameters, $relative ? UrlGeneratorInterface::RELATIVE_PATH : UrlGeneratorInterface::ABSOLUTE_PATH);
    }

    public function getUrl(string $name, array $parameters = [], bool $schemeRelative = false): string
    {
        return $this->generator->generate($name, $parameters, $schemeRelative ? UrlGeneratorInterface::NETWORK_PATH : UrlGeneratorInterface::ABSOLUTE_URL);
    }

}

My original question might shed some background on what I'm looking for.

yivi
  • 42,438
  • 18
  • 116
  • 138
Bradmage
  • 1,233
  • 1
  • 15
  • 41
  • You should be able to get the original output by injecting the environment and doing `$env->getExtension('Symfony\Bridge\Twig\Extension\RoutingExtension')->getUrl($parms)`. I would then alter the output from there. – DarkBee Apr 09 '21 at 07:15
  • 2
    It seems you do not fully understand decoration. Now your service will be called instead of the original. And your service does not include the twig function definitions. – yivi Apr 09 '21 at 07:51
  • @yivi You are correct I only found out about it with my previous question I've listed. I've spent all day researching decoration and have found very little in how to do this start to finish. only snippets, which aren't helpful when I don't know how to incorporate it... – Bradmage Apr 09 '21 at 09:01
  • You need to better understand what decoration is, and how twig extensions are created. If you understand both parts, what follows is trivial. Nico's answer already shown you what you need to add to your decorator. That's all you need for the moment. Good luck. – yivi Apr 09 '21 at 09:05
  • I've created an extension to filter my my urls, I might circle back to this question after playing with extentions a bit more. – Bradmage Apr 10 '21 at 08:36

1 Answers1

1

Where did you define the Twig function path? You've decorated twig.extension.routing without defining any Twig functions. Currently, the method getFunctions of the AbstractExtension is called, and this returns an empty list of functions.

As usual in decoration: if you want to execute any methods on the original service, you need to route such calls through. Something like this might help:

public function getFunctions(): array {
  return $this->router->getFunction();
}

Additionally, you should check the naming of the properties. In the current state, $router does not contain any router, but the Twig extension for routing. To me, this looks pretty confusing, as a proper router would provide completely different methods than a Twig extension does

Nico Haase
  • 11,420
  • 35
  • 43
  • 69
  • I didn't define `path` it is a twig function. It is the function I am trying to modify. – Bradmage Apr 09 '21 at 08:52
  • 1
    Yeah, you didn't define that Twig function, but through decorating the original service, you removed it's definition of that function - `path` is not something like a "built-in function" – Nico Haase Apr 09 '21 at 08:54
  • 1
    I have not tested your solution but I'm pretty sure that it will result in the original getPath being called since getFunctions basically returns pointers to the getPath/getUrl methods. Pretty sure you need to copy/paste RoutingExtension::getFunctions into the decorating service or at least add a TwigFunction to the results. I think I would be tempted to just copy/paste the entire RoutingExtension class and then change the service class name. – Cerad Apr 09 '21 at 11:47