15

我在 Twig 扩展中有一个 slugify 方法,我想在某些情况下在控制器中使用它,fe 带有重定向。
有一个简单的方法吗?
我如何从控制器中的 Twig Extensions 访问功能?

或者我是否必须将 slugify 方法作为助手才能在代码和树枝中使用它?

4

4 回答 4

8

从树枝和控制器访问功能/逻辑

我认为有两种解决方案,都应该使用Twig_Function_Method该类。

1

已经发布的第一个解决方案gilden是将逻辑封装到服务中并为 Twig Extension 制作包装器。

2

另一种解决方案是仅使用 Twig Extension。Twig Extensino 已经是一项服务,您必须使用特殊的<tag name="twig.extension" />. 但它也是一个服务,你可以通过服务容器来抓取哪个实例。也可以注入其他服务:

所以你有你的树枝扩展/服务:

class MyTwigExtension extends \Twig_Extension
{
    private $anotherService;

    public function __construct(SecurityService $anotherService= null)
    {
        $this->anotherService = $anotherService;
    }

    public function foo($param)
    {
       // do something
       $this->anotherService->bar($param);
    }


    public function getFunctions()
    {
        // function names in twig => function name in this calss
        return array(
            'foo' => new \Twig_Function_Method($this, 'foo'),
        );
    }

    /**
     * Returns the name of the extension.
     *
     * @return string The extension name
     */
    public function getName()
    {
        return 'my_extension';
    }
}

services.xml 看起来像这样

<service id="acme.my_extension" class="Acme\CoreBundle\Twig\Extension\MyTwigExtension">
        <tag name="twig.extension" />
        <argument type="service" id="another.service"></argument>
</service>

要从您的控制器访问服务,您只需使用以下命令:
$this->container->get('acme.my_extension')

注意与普通服务的唯一区别是,twig 扩展不是延迟加载的(http://symfony.com/doc/current/cookbook/templating/twig_extension.html#register-an-extension-as-a-service )

于 2013-04-12T12:46:40.433 回答
7

我建议创建一个通用服务并将其注入 Twig 扩展。扩展将充当服务的包装器。

namespace Acme\Bundle\DemoBundle\...;

class MyService
{
    public function myFunc($foo, $bar)
    {
        // some code...
    }

    // additional methods...
}

编辑- 正如 Squazic 所提到的,第一个参数必须实现Twig_ExtensionInterface. 一个不优雅的解决方案是将方法添加到MyTwigExtension,然后调用服务中的相应方法。

namespace Acme\Bundle\DemoBundle\Twig\Extension;

class MyTwigExtension extends \Twig_Extension
{
    protected $service;

    public function __construct(MyService $service)
    {
        $this->service = $service;
    }

    public function getFunctions()
    {
        return array(
            'myTwigFunction' => new \Twig_Function_Method($this, 'myFunc'),
            'mySecondFunc'   => new \Twig_Function_Method($this, 'mySecondFunc'),
        );
    }

    public function myFunc($foo, $bar)
    {
        return $this->service->myFunc($foo, $bar);
    }

    // etc...

}
于 2012-07-11T11:30:34.837 回答
1

或者另一种方法是通过树枝获得它......(这是在 Symfony 2.7 上)

$twigExt = $this->container->get('twig')->getExtension(TwigExtensionClassName::class);

因此,如果您的 Twig 扩展类称为“MyFabulousTwigExt”,那么您将调用

$twigExt = $this->container->get('twig')->getExtension(MyFabulousTwigExt::class);

当上述方法无效时,这对我有用(我们的扩展也不是服务)

于 2018-09-01T10:53:03.203 回答
0

我发现这是直接调用扩展的最佳方式(在 Symfony 4.4 中测试):

use Twig\Environment;

private Environment $twig;

public function __construct(Environment $twig)
{
    $this->twig = $twig;
}

public function foo()
{
    $extensionOutput = $this->twig
        ->getExtension(YourExtension::class)
        ->yourExtensionFunction(
            $this->twig,
            $value
        );
    ...
}

如果您不想(或不能)打破 Twig 扩展的逻辑,这很有用。

于 2022-02-04T18:48:41.973 回答