Symfony,如何在Twig Extension类中生成资产URL?

时间:2012-06-14 17:21:32

标签: symfony twig

我有一个类\Twig_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;
    }

}

我的问题是如何在Twig扩展中生成资产链接?我想在班上替换ASSET助手。我不知道我要注射或使用的是什么!提前致谢。

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

4 个答案:

答案 0 :(得分:16)

您可以直接使用 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 在这种情况下不起作用,因为twig扩展名不能在请求范围内。请参阅此处的文档:http://symfony.com/doc/current/cookbook/service_container/scopes.html#using-a-service-from-a-narrower-scope

答案 1 :(得分:6)

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

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_Extension类代码,并在那里找到了这个initRuntime方法,在我们的自定义Extension类中被覆盖。它接收Twig_Environment作为参数!此对象具有getFunction方法,该方法返回Twig_Function实例。我们只需要传递函数名称(asset,在我们的例子中)。

Twig_Function对象有一个getCallable方法,所以我们最终可以有一个可调用的asset函数。

我进一步为自己的扩展类创建了一个asset方法。在其他任何地方,我只需拨打$this->asset()并在模板中获得与{{ asset() }}相同的结果。

编辑:清除缓存时,getFunction处的initRuntime调用会引发范围异常。所以我将其移至自定义asset方法。它工作正常。

答案 2 :(得分:3)

这是Symfony 2.8的一种简单而干净的方式:

services.yml:

app.twig_extension:
    class: Path\To\AcmeExtension
    arguments:
        assets: "@templating.helper.assets"

在TWIG分机中:

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

class AcmeExtension
{
    protected $assets;

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

然后你可以在扩展的任何功能中使用它,如下所示:

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

答案 3 :(得分:0)

在适用于我的 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';
    }
}