I am working on updating Zikula from Symfony 3 to Symfony 4 (I'm working specifically in this PR at the moment). Part of this is removing Symfony's old templating mechanism and switching entirely to Twig. In the process I am running into a very unusual problem: None of the custom Twig extensions in the included Bundles or the pseudo bundles (they're just Bundles named Modules) are loaded and available in templates.
Yes, the extensions class are autowired and autoloaded and yes they are available - i.e. they are listed in bin/console debug:container
and specifically if I do something like
me% bin/console debug:container AdminExtension
Information for Service "Zikula\AdminModule\Twig\Extension\AdminExtension"
==========================================================================
---------------- --------------------------------------------------
Option Value
---------------- --------------------------------------------------
Service ID Zikula\AdminModule\Twig\Extension\AdminExtension
Class Zikula\AdminModule\Twig\Extension\AdminExtension
Tags twig.extension
Public no
Synthetic no
Lazy no
Shared yes
Abstract no
Autowired yes
Autoconfigured yes
---------------- --------------------------------------------------
! [NOTE] The "Zikula\AdminModule\Twig\Extension\AdminExtension" service or alias has been removed or inlined when the
! container was compiled.
This clearly shows that not only is the service properly autowired, but it is also tagged correctly.
If I do bin/console debug:twig
none of the custom extensions are listed (at the top with functions, filters, etc). I even tried to step through the TwigBundle Compiler process and I am quite sure the callable are being included there.
Do you have any idea what the problem is or how I might troubleshoot it?
The real question I was asking without realizing it was, "What is the correct way to override Twig\Environment
with a child class?"
The correct answer was to define the services in the same exact way as the original. (Symfony uses xml as a default though, so I had to convert). So this is the correct definition:
# override TwigBundle's Twig\Environment definition with Zikula's own child class
# see vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml
twig:
class: Zikula\ThemeModule\Bridge\Twig\EventEnabledTwigEngine
public: true
arguments:
$loader: '@twig.loader'
$options: []
calls:
- [setEventDispatcher, ['@event_dispatcher']]
- [addGlobal, ['app', '@twig.app_variable']]
- [addRuntimeLoader, ['@twig.runtime_loader']]
configurator: ['@twig.configurator.environment', 'configure']
Twig_Environment: '@twig'
Twig\Environment: '@twig'
you can see how this is a copy of Symfony's:
<service id="twig" class="Twig\Environment" public="true">
<argument type="service" id="twig.loader" />
<argument /> <!-- Twig options -->
<call method="addGlobal">
<argument>app</argument>
<argument type="service" id="twig.app_variable" />
</call>
<call method="addRuntimeLoader">
<argument type="service" id="twig.runtime_loader" />
</call>
<configurator service="twig.configurator.environment" method="configure" />
</service>
<service id="Twig_Environment" alias="twig" />
<service id="Twig\Environment" alias="twig" />
and also see how it differs from @Jakumi's suggestion above:
Twig\Environment: Your\Class\Name
Your\Class\Name: # NO DECORATES!!!
arguments: ...
calls: ...
twig: Your\Class\Name # maybe setting it via alias is effective...
Many thanks to @Cerad and @Jakumi for your assistance in solving the problem!