22

For instance my bundle namespace is Facebook\Bundle\FacebookBundle\Extension.

Using this how can I create a twig extension ?

Elnur Abdurrakhimov
  • 44,533
  • 10
  • 148
  • 133
Manish Basdeo
  • 6,139
  • 22
  • 68
  • 102

4 Answers4

34

It's all here: How to write a custom Twig Extension.

1. Create the Extension:

// src/Facebook/Bundle/Twig/FacebookExtension.php
namespace Facebook\Bundle\Twig;

use Twig_Extension;
use Twig_Filter_Method;

class FacebookExtension extends Twig_Extension
{
    public function getFilters()
    {
        return array(
            'myfilter' => new Twig_Filter_Method($this, 'myFilter'),
        );
    }

    public function myFilter($arg1, $arg2='')
    {
        return sprintf('something %s %s', $arg1, $arg2);
    }

    public function getName()
    {
        return 'facebook_extension';
    }
}

2. Register an Extension as a Service

# src/Facebook/Bundle/Resources/config/services.yml
services:
    facebook.twig.facebook_extension:
        class: Facebook\Bundle\Twig\AcmeExtension
        tags:
            - { name: twig.extension }

3. Use it

{{ 'blah'|myfilter('somearg') }}
SpartyDan
  • 75
  • 5
noisebleed
  • 1,299
  • 2
  • 12
  • 26
16

You can also create twig functions by using the getFunctions()

class FacebookExtension extends Twig_Extension
{
    public function getFunctions()
    {
        return array(
            'myFunction' => new Twig_Filter_Method($this, 'myFunction'),
        );
    }

    public function myFunction($arg1)
    {
        return $arg1;
    }

Use your function like this:

{{ myFunction('my_param') }}
Sybio
  • 8,565
  • 3
  • 44
  • 53
15

The Twig_Filter_Method class is DEPRECATED since Symfony 2.1

Please use the Twig_SimpleFilter class instead as showed in the following example:

\src\Acme\Bundle\CoreBundle\Twig\DatetimeExtension.php

<?php

namespace Acme\Bundle\CoreBundle\Twig;

use Symfony\Component\DependencyInjection\ContainerInterface;

class DatetimeExtension extends \Twig_Extension
{
    /**
     * @var \Symfony\Component\DependencyInjection\ContainerInterface
     */
    private $container;

    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
    }

    public function getFilters()
    {
        return array(
            'dateFormat' => new \Twig_SimpleFilter('dateFormat', array($this, 'dateFormat')),
            'datetimeFormat' => new \Twig_SimpleFilter('datetimeFormat', array($this, 'datetimeFormat'))
        );
    }

    /**
     * @param mixed $date
     * @return string
     */
    public function dateFormat($date)
    {
        $format = $this->container->getParameter('acme_core.date_format');
        return $this->format($date, $format);
    }

    /**
     * @param mixed $date
     * @return string
     */
    public function datetimeFormat($date)
    {
        $format = $this->container->getParameter('acme_core.datetime_format');
        return $this->format($date, $format);
    }

    /**
     * @param mixed $date
     * @param string $format
     * @throws \Twig_Error
     * @return string
     */
    private function format($date, $format)
    {
        if (is_int($date) || (is_string($date) && preg_match('/^[0-9]+$/iu', $date))) {
            return date($format, intval($date, 10));
        } else if (is_string($date) && !preg_match('/^[0-9]+$/', $date)) {
            return date($format, strtotime($date));
        } else if ($date instanceof \DateTime) {
            return $date->format($format);
        } else {
            throw new \Twig_Error('Date or datetime parameter not valid');
        }
    }

    public function getName()
    {
        return 'datetime_extension';
    }
}

\src\Acme\Bundle\CoreBundle\Resources\config\services.yml

services:
    acme_core.twig.datetime_extension:
        class: Acme\Bundle\CoreBundle\Twig\DatetimeExtension
        arguments: [@service_container]
        tags:
            - { name: twig.extension }

Usage example:

{{ value|datetimeFormat }}

Symfony documentation: http://symfony.com/doc/master/cookbook/templating/twig_extension.html

Twig documentation: http://twig.sensiolabs.org/doc/advanced.html#id3

Francesco Casula
  • 26,184
  • 15
  • 132
  • 131
2

None of the given answers worked for Symfony 3.4 and above.

For Symfony 3.4, 4.x

// src/TwigExtension/customFilters.php 

namespace App\TwigExtension; 
use Twig\TwigFilter; 

class customFilters extends \Twig_Extension { 

    public function getFilters() { 
        return array( 
            new TwigFilter('base64_encode', array($this, 'base64_en'))
        );
    }

    public function base64_en($input) {
       return base64_encode($input);
    }
}

And then in your twig template you can do

{{ 'hello world' | base64_encode }}

Thats it. For detailed explanation, you could check out the reference.

Reference: DigitalFortress

Niket Pathak
  • 6,323
  • 1
  • 39
  • 51
  • I think this answer may be old, as for building custom Twig extension with `Symfony` 4.x and `Twig` 2.x See next two links: https://symfony.com/doc/current/templating/twig_extension.html and https://symfonycasts.com/screencast/symfony-doctrine/twig-extension – ahmed hamdy Jul 15 '19 at 18:07
  • Have you tested the code? It works exactly as its supposed to with `Symfony 3.4, 4.x` and `Twig 2.x` :) – Niket Pathak Jul 16 '19 at 08:30
  • 1
    First I told may be old not is not work, after checking I figure your code will work correctly But preferred to change `extends \Twig_Extension ` To `extends Twig\Extension\AbstractExtension`, you can check AbstractExtension class will see setting `class_alias('Twig\Extension\AbstractExtension', 'Twig_Extension');` So your code work – ahmed hamdy Jul 17 '19 at 00:11