dark.eye9
dark.eye9

Hi all! I am having a problem where I can't get any Twig Extension to run. Inside vendor/twig/twig/lib/Twig/Extension/ directory we can find some Twig extensions, but they are ot registered by default. I've been searching through the Twig Extension Documentation how to do it but I am not sure how to do it properly and clean.

I grep'ed all the october searching for the Twig initialization code new Twig_Environment and found two probable places:

./modules/system/ServiceProvider.php:75:            $twigEnvironment = new Twig_Environment(new TwigLoader(), ['auto_reload' => true]);
./modules/cms/classes/Controller.php:213:        $this->twig = new Twig_Environment($this->loader, $options);

The second seeming more adequate to me as is the place where October registers his own Twig Extension. But I am a little reticent to include the Extension source and then call addExtension for each one I want to load.

Can you give me some advice?

Last updated

daftspunk
dark.eye9
dark.eye9

Thanks for the answer, but I am not talking about OCtober plugins that want to extend Twig functionality. These are own Twig Extensions that add an extra functionality to the Twig system.

I think it would be too bad to write an October plugin to register them.

sercanvirlan
daftspunk
daftspunk

Can you give an example of what Twig extension you would like to register?

sercanvirlan
sercanvirlan

I wanted to do some eval operation in twig file. I dont know it is possible in another way but i could not do this.

daftspunk
daftspunk

Eval in generic is considered bad practice, let alone doing it inside the template file. If it must be done, do it in the PHP section and pass it to a Twig variable.

Webp
lunfel
lunfel

I was able to load the TwigIntlExtension into a plugin without using the registerMarkupTags method. I used this method because the TwigIntlExtension filters method on the actual classe weren't directly accessible. So I had to get the initialized instance of Twig to register the extension as the Twig doc says to do it http://twig.sensiolabs.org/doc/extensions/intl.html

Basically what it does is that it listens for a page request. On each request it checks if the TwigIntlExtension is loaded. If not, it loads it. The event allows us to have access to the controller thus having access to the initiated Twig Environment.

The hasExtension check is very important because having more than one plugin adding the extension may cause some conflicts. You should add the extension with a check in every plugin that you need it because you don't know in which order they will be registered and you don't want a plugin to depend on another plugin to have the Intlextension.

# class Plugin extends PluginBase

public function boot()
    {
        Event::Listen('cms.page.beforeDisplay', function (Controller $controller, $url, $page) {
            $twigIntlExtension = new \Twig_Extensions_Extension_Intl();

            if (! $controller->getTwig()->hasExtension($twigIntlExtension->getName())) {
                $controller->getTwig()->addExtension($twigIntlExtension);
            }
        });
    }

Available Twig Extensions are located at *root_of_project*/vendor/twig/extensions/lib/Twig/Extensions/Extension

Don't forget to add a composer.json file at the root of your plugin to add the twig/extensions dependency. Then after run the composer update at the root of your project

Hope this will help

Last updated

Mennax
Mennax

This worked for me:

use Twig\Extra\Intl\IntlExtension;
use Event;

class Plugin extends PluginBase
{ 
    public function boot()
    {
        Event::listen('cms.page.beforeRenderPage', function($controller, $page) {
            $twigIntlExtension = new IntlExtension();
            $twig = $controller->getTwig();
            if (! $twig->hasExtension('Twig\Extra\Intl\IntlExtension')) {
                $twig->addExtension($twigIntlExtension);
            }      
        });
    }
}

Last updated

1-10 of 10