user3531149 user3531149 - 2 months ago 19
PHP Question

What's the "right" way to override a symfony extension from another bundle

I need to override the file

It loads the twig getAssetUrl from the bundle using the twig function 'asset'

* Returns a list of functions to add to the existing list.
* @return array An array of functions
public function getFunctions()
return array(
new \Twig_SimpleFunction('asset', array($this, 'getAssetUrl')),
new \Twig_SimpleFunction('assets_version', array($this, 'getAssetsVersion')),

I want to override the asset() twig function without touching the core files, which otherwise would be overridden by the next symfony update

kba kba

Consider that your code live in AppBundle namespace. First create service configuration in app/config.yml or src/AppBundle/Resources/config/something.yml (you have to load this configuration file in bundle extension). Don't forget place it under services key.

    class:     AppBundle\Twig\AssetsExtension
    arguments: ["@service_container", "@?router.request_context"]
    public: false
        - { name: twig.extension }

Now let's create extension src/AppBundle/Twig/AssetsExtension.php. This class inherits from original extension and I will override just one method (in template asset()).


namespace AppBundle\Twig;

class AssetsExtension extends \Symfony\Bundle\TwigBundle\Extension\AssetsExtension
    public function getAssetUrl($path, $packageName = null, $absolute = false, $version = null)
        return parent::getAssetUrl('/something/' . $path, $packageName, $absolute, $version);

Now, after reload, all your assets should be incorrect and prefixed with /something/ by default. You can try to delete Symfony cache in case of problems. I tested this scenario on Symfony 2.5.5.

Another way how to work with built-in services is compiler pass. In compiler pass you can modified whole Symfony service container (delete, replace, modify services). Symfony is all about DIC. I hope it is good enough solution.