Extending Twig in Drupal 8 to Add Your Own Filters

Extending Twig in Drupal 8 to Add Your Own Filters

One of the best changes implemented in Drupal 8 was the implementation of the Twig templating engine. Packed with features, it is light years beyond doing it the old way with native PHP template files (a la Drupal 7 and earlier). However, you may come across the need to "extend" it to add your own capabilities. In this article, we'll explore just how simple it is to add your own content filters to the template engine.

In this simple example, we are going to implement a filter called "colorize" which simply colorizes whatever text you pass into it, along with whatever color you pass into it. Again, this is a simple example which may not have many practical uses, but it should serve as a decent example to get you started creating your own filters.

Initial Setup

To implement a custom Twig filter, we must create a rather simple custom Drupal module. To do so, create a directory under your Drupal install:

$ cd /my/drupal/install/path/modules/custom
$ mkdir TextColorizer
$ cd TextColorizer

This is where we'll be building our filter and module code. Note: the "custom" subdirectory may not exist on your install, so you may need to create that subdirectory as well!

Next, let's create a very simple YML file to describe our new module to Drupal. Call this file TextColorizer.info.yml.

name: TextColorizer
type: module
description: Colorizes text!
core: 8.x
version: '8.x-1.0-beta1'

Nothing much to say about the info.yml file. It basically just tells Drupal what exactly can be found in this directory. Next, we need to create a "services" YML file. This will basically describe and point to our soon-to-be-written filter code: Note: be very careful creating and editing YML files. YML uses spaces, not tabs! Using tabs will result in parsing errors!

# TextColorizer.services.yml
services:
  TextColorizer.twig_extension:
    class: Drupal\TextColorizer\TwigExtension\TextColorizerExtension
    tags:
      - { name: twig.extension }

You may notice that we reference a class called Drupal\TextColorizer\TwigExtension\TextColorizerExtension. This is essentially the "class path" to where our code will reside. So go ahead and create the following directory structure:

$ mkdir -p src/TwigExtension/TextColorizerExtension
$ cd src/TwigExtension/TextColorizerExtension

The Filter Code

Now, we'll create the actual extension/filter code itself. Create a file called TextColorizerExtension.php in the subdirectory we just created (./modules/custom/TextColorizer/src/TwigExtension/TextColorizerExtension).

<?php
namespace Drupal\TextColorizer\TwigExtension;

/**
 * Class DefaultService.
 *
 * @package Drupal\TextColorizer
 */
class TextColorizerExtension extends \Twig_Extension {

  /**
   * {@inheritdoc}
   * This function must return the name of the extension. It must be unique.
   */
  public function getName() {
    return 'TextColorizer.twig_extension';
  }

  /**
   * Generates a list of all Twig filters that this extension defines.
   */
  public function getFilters() {
    return [
      new \Twig_SimpleFilter('colorize', array($this, 'filterColorize'), array('is_safe' => array('html'))),
    ];
  }

  /**
   * Filter to return colorized text
   */
  public static function filterColorize($txt, $color) {
    return '<span style="color: ' . $color . '">Whatever</span>';
  }

}

You can research what each part of the code above does, but here are the highlights:

The getFilters function returns a list of all of the filters you have defined in this class file. You will see that we have created a filter called colorize. You will also see that we have stated that the output of this filter should be considered as "safe HTML". By default, filters output plain text, but since we'll want to colorize our text with this filter, we'll need it to spit out HTML markup.

Using Your New Twig Filter

That's it! Flush your Drupal cache using drush or the admin panel, and install the new "Text Colorizer" module. Now, inside of your twig templates, you can invoke your new "colorize" filter as follows:

{* Some Twig Template *}
{{ "Incursus"|colorize('red') }} {{ "Rocks!"|colorize('#00ff00') }}

We hope you've enjoyed this little tutorial! Be sure to check back often, as we publish all sorts of goodies from time to time, including our internal open source projects!

Peace out.

Tags