覆盖Symfony中的Twig函数

问题描述 投票:1回答:1

能否以及如何重写一个在依赖关系中定义的Twig函数?

ThirdPartyCode\HelloExtension 定义 hello($string name) Twig函数,返回 Hello, {$name}.

在我的代码里 App\MyHelloExtension extends HelloExtension 我想覆盖 hello($string name) 函数返回 Bye, {$name}.

然而,当我用相同的名字定义函数时,第三方的函数被使用,而我的函数从未被调用。如果我给它取不同的名字,如 hello2 它就能正常工作。

symfony twig
1个回答
0
投票

你可以完全替换现有的函数,确保它不会被加载。你可以通过编写一个在构建服务容器的最后一步工作的CompilerPass来实现。这个CompilerPass会通过服务的idclass名称、是否注册来查找服务,然后从容器中删除它。这将完全删除现有的扩展,你可以在它的位置加载你的扩展。

请看 https:/symfony.comdoccurrentservice_containercompiler_passes.html。

或者你可能想使用现有扩展的逻辑,然后在它的基础上构建。对于这种服务,装饰可能是一个很好的选择,因为装饰后的服务会取代原来的服务,同时在必要时仍然可以访问底层装饰的服务。

services:
    App\MyHelloExtension:
        decorates: ThirdpartyCode\Extension
        arguments:
            - '@App\MyHelloExtension.inner' # this passes the decorated service, i.e. the original extension as an argument, see code snippet below

这将确保每当有东西检索服务时 ThirdpartyCode\Extension 的容器中,他们会得到你的扩展。意味着你的扩展将被加载到它的位置。当你的代码扩展了现有的扩展(如在你的代码片段中所看到的)或使用了像这样的合成时,这就特别好用。


class MyHelloExtension extends TwigExtension
{
    private $originalExtension;

    public function __construct(HelloExtension $helloExtension)
    {
        $this->originalExtension = $helloExtension;
    }

    // ...

    public function hello($name)
    {
        // Your method can still utilize the underlying original method if necessary.
        return $this->originalExtension->hello() . ' ' . $name;
    }
}

参见: https:/symfony.comdoccurrentservice_containerservice_decoration.html)。

当你装修服务的时候,你要注意只有一个分机是在Twig注册的。你可能应该确保 autoconfigure: false 设置在你自己的扩展上,并且你没有把它标记为 twig.extension.

© www.soinside.com 2019 - 2024. All rights reserved.