Custom Twig Filters and Functions

Sararellano
4 min readSep 14, 2021

--

Twig Filters and Functions

Twig is the template manager used by Symfony to add some logic to our variables in our templates. The functions and filters problem is that we have a limited number of them. So we are going to learn how to add new filters and functions.

But first… what are filters and functions?

What are filters and functions?

Filters and functions are the logic available in your twig templates. You can see in Twig Documentation the different functions and filters existing. For instance, we have the filter |upper and |lower to put some text uppercase or lowercase. This is the syntax of the filters:

Filter upper

{{ ‘Hello world’|upper }} -> Output HELLO WORLD

And, in the case of functions, you have other examples, like active_theme() to know the theme you are using in Drupal:

Function active_theme()

{{ active_theme() }} -> Output your_theme

But what is the difference between Filters and Functions?

Filters transform the data, but Functions are used when you need to do heavier actions than only show simple datas. The functions are used when you need to calculate things to represent the result (not only show it).

How to add new filters and functions in Twig

In this post we are going to create a filter to convert a number into money € format (moneyFormat), another filter to cut a text and add ‘…’ (cut_text), and also, a function that returns a text in a custom color (color_text).

To do all, we have to have a custom module. In my post, the name of this module will be “MyModule”.

1. Create the service file with this structure: MyModule.services.yml

services:  
MyModule.twig_extension:
class: Drupal\MyModule\MyModuleTwigExtension
tags:
- { name: twig.extension }

2. Now we have to create the file MyModuleTwigExtension.php in the source: MyModule/src/MyModuleTwigExtension.php

Here we are going to declare the class MyModuleTwigExtension and this class will extends from the class Twig_Extension

<?php

namespace Drupal\MyModule;


/**
* Class MyModuleTwigExtension
*/
class MyModuleTwigExtension extends \Twig_Extension {

// A list with all the defined functions. The first parameter is the name by which we will call the function. The second parameter is the name of the function that will implement the function.
public function getFunctions() {
return [
new \Twig_SimpleFunction('color_text', [$this, 'colorText']),
];
}

// A list with all the defined filters. The first parameter is the name by which we will call the filter. The second parameter is the name of the function that will implement the filter.
public function getFilters() {
return [
new \Twig_SimpleFilter('money_format', [$this, 'moneyFormat']),

new \Twig_SimpleFilter('cut_text', [$this, 'cutText']),
];
}

// Returns the extension name
public function getName() {
return 'MyModule.MyModuleTwigExtension';
}


// Function that returns an example text with a color passed as a parameter.
public function colorText($color = "black", $text = 'Lorem ipsum dolor sit amet,
consectetur adipiscing elit. Quos quidem tibi studiose et diligenter
tractandos magnopere censeo.') {
return '<span style="color: ' . $color . '"> ' . $text . ' </span>';
}

// Filter to convert a number into €
public function moneyFormat($string) {
setlocale(LC_MONETARY, 'es_ES.UTF-8');
return money_format('%i', $string);
}


// Filter that cuts a text according to the maximum number of characters. You can also choose which characters will be put at the end of the text. By default is ‘...’
public function cutText($text, $maxchar, $end = '...') {
if (strlen($text) > $maxchar || $text == '') {
$words = preg_split('/\s/', $text);
$output = '';
$i = 0;
while (1) {
$length = strlen($output)+strlen($words[$i]);
if ($length > $maxchar) {
break;
}
else {
$output .= " " . $words[$i];
++$i;
}
}
$output .= $end;
}
else {
$output = $text;
}
return $output;
}

}

Now, you have to clean the cache and… that’s all! You can use your new filter and your new function in your templates.

The syntax will be:

{# Function #}
{{ color_text('orange')|raw }}
{{ color_test('green', 'I am testing the new function')|raw }}

{# Filters #}
{{ '150'|money_format }} // Output: 150,00 EUR
{{ 'Hello! We are learning how to create new twig extensions'|cut_text(15) }}
// Output: Hello! We are...
{{ 'Hello! We are learning how to create new twig extensions'|cut_text(15, '-') }}
// Output: Hello! We are-

Another interesting thing is that Twig variables can be modified by filters. Also, you can add more than 1 filter in a variable, so the output of the first filter will be affected by the second filter:

{{ ‘I am going to cut this text’|cut_text(10)|upper }}

For more information, you can see the documentation from Symfony about how to do that.

--

--