Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony - Unable to register extension "AppBundle\Twig\Extension\FileExtension" as it is already registered

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?

like image 994
liestack Avatar asked Sep 03 '17 17:09

liestack


2 Answers

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.

like image 150
Ziad Akiki Avatar answered Oct 23 '22 00:10

Ziad Akiki


This question still has no actual answer, imho.

First, Twig doesn't render twice, but it tries to register your extension twice. However Twig only allows to register a specific class as extension, once.

So, why is Twig trying to register it twice?

Because there are two services now with the same class and with respective tags which tell Twig that those services are twig extensions.

But why are there two services?

Well, there is one defined manually: app.twig.file_extension

and another one is defined automatically by this configuration in the default services.yml:

App\:
    resource: '../src/*'
    exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'

Cerad's comment is pointing to the autoconfigure docs, which I think is misleading. With autoconfigure, Symfony will automatically apply the twig tags to the second (automatically configured) service.

So, yes, you can solve this problem, by turning autoconfigure off. Then you have two services, but only the manualy configured one has the tags required to be reckognized as twig extension.

Ziad Akiki's answer quotes the docs stating that you don't need further configuration. But just because you don't need doesn't mean you can not and I can even imagine valid use cases. That's why I think it is not an actual answer. Actually, you can, by simply naming the service entry after its class name:

services:
    AppBundle/Twig/Extensions/FileExtension:
        tags:
            - { name: 'twig.extension' }
like image 25
fishbone Avatar answered Oct 23 '22 01:10

fishbone