【问题标题】:How to use Symfony Decorator pattern to change a Twig function?如何使用 Symfony 装饰器模式来更改 Twig 功能?
【发布时间】:2021-07-05 01:34:54
【问题描述】:

我正在尝试更改{{ url('app_route_name') }} or {{ path('app_route_name') }} 的输出。通常输出可能是/app/route/name 我只想修改树枝输出。

我的第一次尝试是装饰 UrlGenerator->generate,但更改 $name 也会更改调用的控制器。我只是想改变最终的输出。

这是我目前正在尝试的代码。我得到的错误异常是:

未知的“路径”功能。您是说“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);
    }

}

我原来的question 可能会为我正在寻找的东西提供一些背景。

【问题讨论】:

  • 您应该能够通过注入环境并执行$env->getExtension('Symfony\Bridge\Twig\Extension\RoutingExtension')->getUrl($parms) 来获得原始输出。然后我会改变那里的输出。
  • 看来你还没有完全了解装修。现在将调用您的服务而不是原始服务。而且您的服务不包括树枝函数定义。
  • @yivi 你是对的,我只是在我之前列出的问题中发现了它。我花了一整天的时间研究装饰,但几乎没有发现如何从头到尾做到这一点。只有sn-ps,当我不知道如何合并它时没有帮助......
  • 您需要更好地了解装饰是什么,以及如何创建树枝扩展。如果您了解这两个部分,那么接下来的内容就很简单了。 Nico 的回答已经向您展示了您需要添加到装饰器中的内容。这就是你目前所需要的。祝你好运。
  • 我已经创建了一个扩展来过滤我的网址,我可能会在多玩一些扩展之后回到这个问题。

标签: php symfony twig decorator


【解决方案1】:

你在哪里定义了 Twig 函数path?您已经装饰了 twig.extension.routing 而不定义任何 Twig 函数。目前调用的是 AbstractExtension 的 getFunctions 方法,这会返回一个空的函数列表。

像往常一样装饰:如果你想在原始服务上执行任何方法,你需要路由这样的调用。这样的事情可能会有所帮助:

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

此外,您应该检查属性的命名。在当前状态下,$router 不包含任何路由器,而是用于路由的 Twig 扩展。对我来说,这看起来很令人困惑,因为合适的路由器会提供与 Twig 扩展完全不同的方法

【讨论】:

  • 我没有定义path它是一个twig函数。这是我要修改的功能。
  • 是的,你没有定义那个 Twig 函数,但是通过装饰原始服务,你删除了它对那个函数的定义 - path 不像“内置函数”跨度>
  • 我尚未测试您的解决方案,但我很确定它会导致调用原始 getPath,因为 getFunctions 基本上返回指向 getPath/getUrl 方法的指针。很确定您需要将 RoutingExtension::getFunctions 复制/粘贴到装饰服务中,或者至少在结果中添加一个 TwigFunction。我想我会很想复制/粘贴整个 RoutingExtension 类,然后更改服务类名称。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-09
  • 2021-11-24
  • 2022-08-15
  • 2013-05-07
  • 2013-07-30
相关资源
最近更新 更多