2
votes

I add pictures over assetic like this:

{% image '@MyBundle/Resources/public/img/name.png' %} 
  <img src="{{ asset_url }}"/>
{% endimage %}

works fine for me, but I would like to write less, so I tryed to create a twig function like in the symfony2 docu. But I don't use any filter:

assetic:
    debug:          "%kernel.debug%"
    use_controller: false
    bundles:        [MyBundle]
    #java: /usr/bin/java
    filters:
        cssrewrite: ~
    twig:
        functions:
            timg: ~

But if I now use it:

<img src="{{ timg('@MyBundle/Resources/public/img/name.png') }}" />

I get the exception:

An exception has been thrown during the compilation of a template ("Catchable Fatal Error: Argument 3 passed to Twig_Node_Expression_GetAttr::__construct() must be an instance of Twig_Node_Expression_Array, instance of Twig_Node given, called in C:\wamp2\www\symfony\vendor\symfony\assetic-bundle\Symfony\Bundle\AsseticBundle\Twig\AsseticNodeVisitor.php on line 66 and defined in C:\wamp2\www\symfony\vendor\twig\twig\lib\Twig\Node\Expression\GetAttr.php line 14") in "::top.html.twig".

Any ideas? Maybe I can't use just function for short syntax without a filter?

2
symfony.com/doc/current/cookbook/assetic/… here I got the idea for this short sintaxdegressor

2 Answers

1
votes

I would suggest you to define a very simple filter and use it like {{ 'mypath'|timg }}:

class ImgExtension extends \Twig_Extension
{
    private $asset;
    public function __construct(Container $c){
        $this->asset = $c->get('templating.helper.assets');
    }
    public function getFilters(){
        return array('timg' => new \Twig_Filter_Method($this, 'timg'));
    }
    public function timg($src, $package = null) {
        $url = $this->asset->getUrl($src, $package);
        return '<img src="'.$url.'" />';
    }
    public function getName(){
        return 'timg';
    }
}

Then you could add some other useful parameters, such as alt, title, etc.

0
votes

Your function name needs to map to a filter name.

For instance:

assetic:
    debug:          "%kernel.debug%"
    use_controller: false
    bundles:        [MyBundle]
    filters:
        cssrewrite: ~
    twig:
        functions:
            cssrewrite: ~

Allows you to do:

<link rel="stylesheet" href="{{ cssrewrite('bundles/my/css/style.css') }}" />

This simply illustrates the syntax: using cssrewrite as a function works on dev, but not prod — without uncovering the exact reason I'd reitterate the advice that assetic-filter-functions-in-twig are best suited for image based filters.

In order to use timg as a function in the same way it must be defined as an assetic filter first. You'd have to implement it first as a custom assetic filter.

At a glance @alexcasalboni's answer provides a nice example of implementing a twig filter, and appears to be less configuration than setting up an assetic filter in symfony.