问题
When I try to implement custom Twig Extension in Symfony2-project, I get following error:
Unable to register extension "AppBundle\Twig\Extension\FileExtension" as it is already registered.
In my app/config/services.yml, I have following:
parameters:
app.file.twig.extension.class: AppBundle\Twig\Extension\FileExtension
services:
app.twig.file_extension:
class: '%app.file.twig.extension.class%'
tags:
- { name: 'twig.extension' }
In AppBundle/Twig/Extensions/FileExtension, i have:
<?php
namespace AppBundle\Twig\Extension;
class FileExtension extends \Twig_Extension
{
/**
* Return the functions registered as twig extensions
*
* @return array
*/
public function getFunctions()
{
return array(
new \Twig_SimpleFunction('file_exists', array($this, 'file_exists')),
);
}
public function getName()
{
return 'app_file';
}
}
?>
I tried to clear cache, but not working. Anybody ideas why Twig renders twice?
回答1:
As @Cerad said, starting with Symfony 3.3, the twig extensions are automatically loaded and there is no need to define anything in the default services.yml.
Per the official documentation:
If you're using the default services.yml configuration, you're done! Symfony will automatically know about your new service and add the tag.
回答2:
In symfony 4, if you have autowire you can forget of configuring the services.yaml, your code would look the same in your services, only change the folder´s path.
namespace App\Util;
use Symfony\Component\HttpKernel\KernelInterface;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;
class RemoteFileExtension extends AbstractExtension
{
private $kernel;
public function __construct(KernelInterface $kernel)
{
$this->kernel = $kernel;
}
public function getFunctions()
{
return array(
new TwigFunction('remote_file', array($this, 'remoteFile')),
);
}
public function remoteFile($url)
{
$contents = file_get_contents($url);
$file = $this->kernel->getRootDir() . "/../templates/temp/" . sha1($contents) . '.html.twig';
if (!is_file($file))
{
file_put_contents($file, $contents);
}
return '/temp/' . basename($file);
}
public function getName()
{
return 'remote_file';
}
}
回答3:
I had the same error in a Symfony 3.4 project.
It was a dependency injection of a custom TechnicianService into the twig extension that was causing this error in my case. After a lot of trial and error the solution was to move the specific function from the TechnicianService to a function into a TechnicianRepository and then inject the EntityManagerInterface into the twig extension, from which I could access my moved function again.
So in the beginning I had
class FindTechnicianByUrlExtension extends \Twig_Extension
{
private $technicianService;
/**
* @param TechnicianService $technicianService
*/
public function __construct(TechnicianService $technicianService)
{
$this->technicianService = $technicianService;
}
public function getFunctions()
{
return [
new \Twig_SimpleFunction('findTechnicianByUrl', function ($url) {
return $this->technicianService->findTechnicianByUrl($url);
})
];
}
}
That had to change to this:
class FindTechnicianByUrlExtension extends \Twig_Extension
{
private $em;
/**
* @param EntityManagerInterface $em
*/
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
}
public function getFunctions()
{
return [
new \Twig_SimpleFunction('findTechnicianByUrl', function ($url) {
return $this->em->getRepository(Technician::class)->findTechnicianByUrl($url);
})
];
}
}
It is a legacy project. Some older services are not autowired, maybe configured differently,... My new Twig extension uses autowire. Don't know what caused the problem but I did fix it. If somebody knows the exact cause by reading my solution, please let me know.
来源:https://stackoverflow.com/questions/46026221/symfony-unable-to-register-extension-appbundle-twig-extension-fileextension