Symfony,如何在细枝扩展类中生成资产URL?

Symfony,如何在细枝扩展类中生成资产URL?,symfony,twig,Symfony,Twig,我有一个类扩展了\Twig\u Extension,如下所示: class MYTwigExtension extends \Twig_Extension { protected $doctrine; protected $router; public function __construct(RegistryInterface $doctrine , $router) { $this->doctrine = $doctrine;

我有一个类扩展了
\Twig\u Extension
,如下所示:

class MYTwigExtension extends \Twig_Extension
{

    protected $doctrine;

    protected $router;


    public function __construct(RegistryInterface $doctrine , $router)
    {
        $this->doctrine = $doctrine;
        $this->router = $router;

    }

    public function auth_links($user , $request)
    {
       // Some other codes here ...

       // HOW TO GENERATE $iconlink which is like '/path/to/an/image'

       $html .= "<img src=\"$iconlink\" alt=\"\" />  ";  

       echo $html;
    }

}
类MyTwigeExtension扩展\Twig\u扩展
{
受保护的美元原则;
受保护的路由器;
公共函数构造(RegistryInterface$原则,$路由器)
{
$this->doctrine=$doctrine;
$this->router=$router;
}
公共函数auth_链接($user,$request)
{
//这里还有一些其他代码。。。
//如何生成类似“/path/TO/an/image”的$iconlink
$html.=”;
echo$html;
}
}
我的问题是如何在细枝扩展中生成资产链接?我想替换我班上的资产助手。基本上,我不知道我必须在这里注射或使用什么!提前谢谢

 <img src="{{ asset('img/icons/modules/timesheet.png') }}" alt="" /> 

您可以直接使用templating.helper.assets服务

use Symfony\Component\DependencyInjection\ContainerInterface;

public function __construct(ContainerInterface $container)
{
    $this->container = $container;
}
并像这样使用它:

$this->container->get('templating.helper.assets')->getUrl($iconlink);

在这种情况下,直接注入templating.helper.assets不起作用,因为细枝扩展不能在请求范围内。请参阅此处的文档:

我不想处理依赖项注入容器。这就是我所做的:

use Twig_Environment as Environment;

class MyTwigExtension extends \Twig_Extension
{
    protected $twig;
    protected $assetFunction;

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

    protected function asset($asset)
    {
        if (empty($this->assetFunction)) {
             $this->assetFunction = $this->twig->getFunction('asset')->getCallable();
        }
        return call_user_func($this->assetFunction, $asset);
    }
我查看了
Twig_扩展
类代码,发现该
initRuntime
方法将在自定义扩展类中被重写。它接收Twig_环境作为参数!这个对象有一个
getFunction
方法,它返回一个
Twig\u函数
实例。我们只需要传递函数名(
asset
,在本例中)

Twig_函数
对象有一个
getCallable
方法,因此我们最终可以有一个可调用的
asset
函数

我进一步为自己的扩展类创建了一个
asset
方法。在它的任何其他地方,我都可以简单地调用
$this->asset()
,并获得与模板中的
{{asset()}}
相同的结果


EDIT:在
initRuntime
处调用
getFunction
在清除缓存时引发作用域异常。因此,我将其移动到自定义
asset
方法。它工作得很好。

在对我有效的Symfony 2.8中:

# services.yml
services:
    app.twig_extension:
        class: AppBundle\Twig\AppTwigExtension
        public: false
        arguments:
            - @templating.helper.assets
        tags:
            - { name: twig.extension }
AppTwigExtension类:

namespace AppBundle\Twig;

use Symfony\Bundle\FrameworkBundle\Templating\Helper\AssetsHelper;

/**
 * Class AppTwigExtension
 * @package AppBundle\Twig
 */
class AppTwigExtension extends \Twig_Extension
{
    const IMG_PATH = 'bundles/app/images/';

    private $assetsHelper;

    public function __construct(AssetsHelper $assetsHelper)
    {
        $this->assetsHelper = $assetsHelper;
    }

    public function getFilters()
    {
        return array(
            new \Twig_SimpleFilter('img', array($this, 'imagePathFilter'))
        );
    }

    /**
     * Get image path relatively to host
     * Usage in Twig template: {{ 'my_image.png'|img }} - equal to
     * {{ asset('bundles/app/images/my_image.png') }} in Twig template:
     *
     * @param string $imageName (e.g. my_image.png)
     * @return string
     */
    public function imagePathFilter($imageName)
    {
        return $this->assetsHelper->getUrl(self::IMG_PATH . $imageName);
    }

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

以下是Symfony 2.8的一种简单明了的方法:

services.yml:

app.twig_extension:
    class: Path\To\AcmeExtension
    arguments:
        assets: "@templating.helper.assets"
在细枝扩展中:

use Symfony\Bundle\FrameworkBundle\Templating\Helper\AssetsHelper;

class AcmeExtension
{
    protected $assets;

    public function __construct(AssetsHelper $assets)
    {
        $this->assets = $assets;
    }
}
然后您可以在扩展的任何函数中使用它,如下所示:

$this->assets->getUrl('myurl');

我应该在config.yml中注入什么?“@what”?服务id是“templating.helper.assets”。因此@templating.helper.assets应该可以。如果您尝试注入templating.helper.assetsa,它会对范围产生抱怨。我明白了,您必须将
scope:request
添加到您的服务定义中。或者,您可以注入容器本身,然后调用$this->container->get('templating.helper.assets')也可以。是的,我确实注入了容器“@service\u container”,我使用了$this->container->get('templating.helper.assets')。谢谢,谢谢你。我更喜欢这种方法,而不是注入容器。现在,这种方法会触发一个弃用警告,可以通过实现
Twig\u扩展\u InitRuntimeInterface
或通过注入
Twig\u环境重新编写代码来修复: