Custom twig function and filter in Drupal 8

Custom twig function and filter

Twig is a part of the Symfony framework and introduced as a template engine. Drupal 8 also uses twig as a template engine.

We can modify incoming data to twig using Drupal 8 template hooks but we also need some quick filter and dynamic functions that we can directly inject to a particular template.

Drupal 8 provides a way to create custom twig extension, Let’s how we can do this.

1. Declare your custom module using the info.yml file. Here our example module name is “Twig Extension” (twig_extension). [file name:- twig_extension.info.yml]

name: Twig Extension
type: module
description: 'Twig custom extension - Filter and function'
package: Theme
core: 8.x

2. Now declare a twig extension service as below. [file name:-twig_extension.services.yml]

services:
  twig_extension.function:
    class: Drupal\twig_extension\TwigExtension\TwigFunctionExtension
    tags:
      - { name: twig.extension }
  twig_extension.filter:
    arguments: ['@renderer']
    class: Drupal\twig_extension\TwigExtension\TwigFilterExtension
    tags:
      - { name: twig.extension }

Make sure to use service tag twig extension, This will tell Drupal 8 that this service is for twig extension.

3. Create a twig filter using the Twig_SimpleFilter class. [file name:-TwigFilterExtension.php]

<?php
namespace Drupal\twig_extension\TwigExtension;
/**
 * Class TwigFilterExtension.
 */
class TwigFilterExtension extends \Twig_Extension{
  /**
   * Declare your custom twig filter here
   *
   * @return array|\Twig_SimpleFilter[]
   */
  public function getFilters()
  {
    return [ 
      new \Twig_SimpleFilter(
        'remove_links', 
        array($this, 'removeLinks')
      )
    ];
  }
  /**
   * Function to remove only links from the html
   * @param $string
   *  Html as string
   *
   * @return string
   *  Filtered html
   */
  public static function removeLinks($string)
  {
    return preg_replace('#<a.*?>(.*?)</a>#i',
      '\1',
      $string);
  }
  /**
   * {@inheritdoc}
   * @return string
   */
  public function getName()
  {
    return 'twig_extension.filter';
  }
}

4. Create a twig function using class Twig_SimpleFunction. [file name:- TwigFunctionExtension.php]

<?php
namespace Drupal\twig_extension\TwigExtension;
/**
 * Class TwigFunctionExtension.
 */
class TwigFunctionExtension extends \Twig_Extension {
  /**
   * Declare your custom twig extension here
   *
   * @return array|\Twig_SimpleFunction[]
   */
  public function getFunctions() {
    return array(
      new \Twig_SimpleFunction('display_block_by_id',
        array($this, 'display_block'),
        array('is_safe' => array('html'))
      )
    );
  }
  /**
   * Function to get and render block by id
   * @param $block_id
   *  Block id to render
   *
   * @return array
   */
  public function display_block($block_id) {
    $block = \Drupal\block\Entity\Block::load($block_id);
    return \Drupal::entityTypeManager()
      ->getViewBuilder('block')
      ->view($block);
  }
  /**
   * {@inheritdoc}
   * @return string
   */
  public function getName() {
    return 'twig_extension.function';
  }
}

Very rarely we need to develop custom twig function and filter in Drupal 8 but we can successfully do this as described above.