Search code examples
symfonysymfony4twig-extension

Symfony 4.1 twig extension


In Symfony 4.1 I created an twig extension and I tried to use it as an service

twig.extension.active.algos:
    class: App\Twig\AppExtension
    public: true
    tags:
        - { name: twig.extension, priority: 1024 }

Unfortunately I receive 'Unable to register extension "App\Twig\AppExtension" as it is already registered' After many searches I saw that there was a bag in the version of symfony 3.4 but they say the error would have solved. So it's my mistake or just another mistake from symfony team.

My extension is:

use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;

class AppExtension extends \Twig_Extension {

public function getFunctions() {
    return array(
        new \Twig_SimpleFunction('get_active_algos', array($this, getActiveAlgos')),
    );
}

public function getActiveAlgos()
{
    return [1,2,3];
}

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

Solution

  • Got bored. Here is a working example of a custom twig function for S4.1. No service configuration required (Update: except for the added $answer argument). I even injected the default entity manager using autowire just because.

    namespace App\Twig;
    
    use Doctrine\ORM\EntityManagerInterface;
    use Twig\Extension\AbstractExtension;
    use Twig\TwigFunction;
    
    class TwigExtension extends AbstractExtension
    {
        private $em;
        private $answer;
    
        public function __construct(EntityManagerInterface $em, int $answer)
        {
            $this->em = $em;
            $this->answer = $answer;
        }
        public function getFunctions()
        {
            return array(
                new TwigFunction('get_active_algos', [$this, 'getActiveAlgos']),
            );
        }
        public function getActiveAlgos()
        {
            $dbName = $this->em->getConnection()->getDatabase();
            return 'Some Active Algos ' . $dbName . ' ' . $answer;
        }
    }
    

    Update: Based on the first comment, I updated the example to show injecting a scaler parameter which autowire cannot handle.

    # services.yaml
    App\Twig\TwigExtension:
        $answer: 42
    

    Note that there is still no need to tag the service as an extension. Autoconfig takes care of that by automatically tagging all classes which extend the AbstractExtension.