I have one class which extends \Twig_Extension
like below :
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;
}
}
My question is How to generate Asset links in a Twig Extension ? I would like a replacement for ASSET helper in my class. Bassically I have no idea what I have to inject or use here ! Thanks in advance.
<img src="{{ asset('img/icons/modules/timesheet.png') }}" alt="" />
You can use the templating.helper.assets service directly.
use Symfony\Component\DependencyInjection\ContainerInterface;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
and use it like so:
$this->container->get('templating.helper.assets')->getUrl($iconlink);
Injecting just the templating.helper.assets directly does not work in this case because the twig extension cannot be in the request scope. See the documentation here: https://symfony.com/doc/2.3/cookbook/service_container/scopes.html#using-a-service-from-a-narrower-scope
I didn't want to deal with the Dependency Injection Container. This is what I did:
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);
}
I've looked at Twig_Extension
class code, and found this initRuntime
method there, to be overriden in our custom Extension class. It receives the Twig_Environment
as an argument! This object has a getFunction
method, which returns a Twig_Function
instance. We only need to pass the function name (asset
, in our case).
The Twig_Function
object has a getCallable
method, so we finally can have a callable asset
function.
I've gone a bit further creating an asset
method for my own extension class. Anywhere else on it, I can simply call $this->asset()
and obtain the same result as {{ asset() }}
in the templates.
EDIT: The getFunction
call at initRuntime
throws a scope exception when clearing the cache. So I moved it to the custom asset
method. It works fine.
Here's a simple and clean way for Symfony 2.8:
services.yml:
app.twig_extension:
class: Path\To\AcmeExtension
arguments:
assets: "@templating.helper.assets"
In the TWIG extension:
use Symfony\Bundle\FrameworkBundle\Templating\Helper\AssetsHelper;
class AcmeExtension
{
protected $assets;
public function __construct(AssetsHelper $assets)
{
$this->assets = $assets;
}
}
Then you can use it in any function of the extension like this:
$this->assets->getUrl('myurl');
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With