15.08.11 - Extending Twig in Symfony 2, add custom functions

How to add functions to Twig in Symfony 2

Sometimes we need to add some custom functions to the view. In Symfony 1 we have the helpers, in Symfony 2 we must extend Twig in order to add it.

At first, we have to connect our future Twig extension to the Dependency Injection Container in our Bundle. If we don't got any config file we have to create it.
<?php
# Test/MyBundle/DependencyInjection/MyBundleExtension.php

namespace Test\MyBundle\DependencyInjection;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\Config\FileLocator;

class TestMyBundleExtension extends Extension
{
    public function load(array $configs, ContainerBuilder $container)
    {
        $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
        $loader->load('twig.xml');
    }

    public function getAlias()
    {
        return 'test_my_bundle';
    }
}
At this point we have to configure what kind of service we will offer, the parameters that it will require and how is going to be connected to the kernel (file Test/MyBundle/Resources/config/twig.xml):
<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>
        <service id="twig.extension.ka.blog" class="Test\MyBundle\Twig\Extension\BlogExtension" public="false">
            <tag name="twig.extension" />
        </service>
    </services>
</container>
Once done, the last step is to extend Twig with an Extension. In this case we will add a simple function that transforms a string into a Unix timpestamp:
<?php
# Test/MyBundle/Twig/Extension/MyBundleExtension.php

namespace Test\MyBundle\Twig\Extension;

use Symfony\Component\HttpKernel\KernelInterface;

class MyBundleExtension extends \Twig_Extension
{
    public function __construct()
    {
    }

    /**
     * {@inheritdoc}
     */

    public function getFunctions()
    {
        return array(
            'totime' => new \Twig_Function_Method($this, 'toTime')
        );
    }
   
    /**
     * Converts a string to time
     *
     * @param string $string
     * @return int
     */

    public function toTime ($string)
    {
        return strtotime($string);
    }

    /**
     * Returns the name of the extension.
     *
     * @return string The extension name
     */

    public function getName()
    {
        return 'my_bundle';
    }
}
Thats all! To use it under your templates you only have to enter:
{{ totime(strtime) }}
More news about:  php,  Symfony2
Tags:  php,  Twig,  Extension,  Kernel,  Bundle

Comments

  • Gravatar
    14.10.11 - 02:19  Nico

    Great article, thanks!

  • Gravatar
    17.11.11 - 12:13  Tom

    While it may be a nice idea to use Symfony's dependency injection mechanism, I found this to be a lot easier: namespace Bundle\MyBundle; use Bundle\MyBundle\Twig\Extension\MyExtension; class MyBundle extends Bundle { public function boot() { $extension = new MyExtension(); $this->get('twig')->addExtension($extension); } } Two lines of code should be good enough for anybody. Why so complicated if there is an easy way that just works?

  • Gravatar
    18.11.11 - 12:22  Bradley Colosimo

    Hello dude! I’ve just stopped by to say thanks for this cool site! Keep going that way.

  • Gravatar
    24.11.11 - 10:44  Dione Canes

    Hi man! Nice resource! I really liked being here.

  • Gravatar
    16.12.11 - 03:43  Rich

    @Tom - doing it your way removes the ability to be able to override the extension class if eg I wanted to use your bundle and drop in a replacement. Using the provided DI mechanisms removes this restriction.

  • Gravatar
    05.09.12 - 01:01  domis

    Thx man! This was missing from symdony docs :)

Comment