Twig is the default templating system used by the popular php framework symfony. Twig is a

complete, powerful, easy to use library. The purpose of this article is to describe how to add 

filters and functions.

Twig filters are methods used to change variables passed to them:

`{ { dataCreazione|date("d/m/Y") } }`

This example formats a *date* type variable so that its format becomes dd/mm/yy. The filter 

automatically takes as first function parameter the variable preceding |. 

Instead functions are simply functions, as their name suggests!

`{ { dump(dataCreazione) } }`

The dump functions performs a var_dump of the variable passed as first argument. 

Filters are usually meant to change the view of passed variables. Functions are used for more 

complex calculations.

You can find a list of functions and filters available in twig in the documentation page.

You can start writing your first filter.

Note: The following examples are only hints and suggestions, as they need to be completed, 

adding the needed name space, checks and exceptions. 

First you need to find a symfony service:

class CustomExtension extends Twig_Extension
    {
    	public function getFilters()
        {
            return array(
                new Twig_SimpleFilter("baseConvert", array($this, "baseConvert")),
            );
        }
    
	    public function baseConvert($num, $baseFrom = 10, $baseTo = 2)
	    {
		    return base_convert($num, $baseFrom, $baseTo);
	    }
    }

Let's have a closer look at the service. There are two methods: getFilters, returning an array of 

available filters, and baseConvert function, the one to be used as twig filter. 

A Twig_SimpleFilter object takes as first argument the string to be used as filter in the template, 

followed by a callable element (so you can use external classes, php native functions or 

closures). You can choose as third argument an array of options, very useful if you need to print 

HTML, e.g., 'array('is_safe' => array('html'))'.

Once created your filter, you need to use it within a twig template. The only way to proceed is 

registering your service in symphony, adding the twig.extension tag

xxx.twig.custom_extension:
        class: ...CustomExtension
        tags:
            - { name: twig.extension }

Now you can recall your filter, like this: 

{ { numero|baseConvert } }

If for example the value of 'number' argument is 10, the filter will output 1010.

But, due to the way the function is written, you can also pass parameters to it:

{ { numero|baseConvert(2, 10) } }

In this case, if the value of 'number' argument is 10, the filter will output 2.

Now the service can be modified to add a function. Imagine you want to write the number of a 

user's messages next to his name, counting them from a table of messages:

class CustomExtension extends Twig_Extension
    {
    	/**
         * @var SymfonyComponentDependencyInjectionContainerInterface
         */
        private $container;
    
        /**
         * @param ContainerInterface $container
         */
        public function __construct(ContainerInterface $container)
        {
            $this->container = $container;
        }
	    ...
    }

First, you need to change your service, so that it can accept the symfony container.

xxx.twig.custom_extension:
    class: ...CustomExtension
    arguments:
        - @service_container
    tags:
        - { name: twig.extension }

Then you can write your method countMessages, after registration of the repository of 

messages as a service:

public function contaMessaggi(User $user)
{
    return count($this->container->get("xxx.repository.messaggi")->findByUser($user));
}

Now you need to implement in CustomExtension the getFunctions method, needed to make 

available your functions to twig, in the same way as getFilters does with filters.

public function getFunctions()
{
    	return array("contaMessaggi" => new Twig_Function_Method($this, "contaMessaggi"));
}

The Twig_Function_Method object takes as first argument a Twig_ExtensionInterface and as 

second argument the name of method to call.

So you can use your function in twig:

{ { contaMessaggi(user) } }

you need to pass a variable containing a type User object, as required by your method.

You can also make available "global" variables to all twig templates. This is useful if you need to 

use configuration variables.

For this purpose, you can implement the *getGlobals* method in a service having 

twig_extension tag. 

public function getGlobals()

Alessandro Nuzzo

Senior Web Developer , Website , Git home page , @aleinside , Linkedin profile
I am a developer since 2006. I am a basket and whisky lover, interests that i follow separately for obvious reasons. I am also the Milan PHP User Group founder and coordinator.

All articles by Alessandro Nuzzo

Comments

comments powered by Disqus

cloudparty

Follow Us