Создание своего расширения для Twig

В Twig имеется множество расширений, которые удобно использовать в шаблонах. Однако может возникнуть ситуация, когда будет необходимо написать собственное расширение. Например мы хотим отображать даты в формате: 2 дня назад, 3 месяца назад и т.п.

Пусть это расширение используется следующим образом:

{{ comment.created|created_ago }}

1. Сперва создадим файл для Twig расширения по адресу src/Acme/TestBundle/Twig/Extensions/AcmeTestExtension.php со следующим содержимым:

<?php
// src/Acme/TestBundle/Twig/Extensions/AcmeTestExtension.php

namespace Acme\TestBundle\Twig\Extensions;

class AcmeTestExtension extends \Twig_Extension
{
    public function getFilters()
    {
        return array(
            'created_ago' => new \Twig_Filter_Method($this, 'createdAgo'),
        );
    }

    public function createdAgo(\DateTime $dateTime)
    {
        $delta = time() - $dateTime->getTimestamp();
        if ($delta < 0)
            throw new \InvalidArgumentException("createdAgo is unable to handle dates in the future");

        $duration = "";
        if ($delta < 60)
        {
            // Seconds
            $time = $delta;
            $duration = $time . " second" . (($time > 1) ? "s" : "") . " ago";
        }
        else if ($delta <= 3600)
        {
            // Mins
            $time = floor($delta / 60);
            $duration = $time . " minute" . (($time > 1) ? "s" : "") . " ago";
        }
        else if ($delta <= 86400)
        {
            // Hours
            $time = floor($delta / 3600);
            $duration = $time . " hour" . (($time > 1) ? "s" : "") . " ago";
        }
        else
        {
            // Days
            $time = floor($delta / 86400);
            $duration = $time . " day" . (($time > 1) ? "s" : "") . " ago";
        }

        return $duration;
    }

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

Создание расширения осуществляется очень просто. Мы изменим метод getFilters() так, чтобы можно было возвращать любое количество филтров, которые нам нужны. В данном случае мы создаем фильтр created_ago. Далее этот фильтр мы регистрируем для использования в методе createdAgo, который будет просто трансформировать формат даты DateTime объекта в строку, представляющую продолжительность времени, прошедшего с тех пор, как было сохранено первоначальное значение объекта DateTime object.

2. Далее зарегистрируем наше новое расширение в файле конфигурации - src/Acme/TestBundke/Resources/config/services.yml следующим образом:

services:
    blogger_blog.twig.extension:
        class: Blogger\BlogBundle\Twig\Extensions\BloggerBlogExtension
        tags:
            - { name: twig.extension }

3. Теперь новый фильтр готов к использованию! Есть ряд полезных расширений Twig доступных в библиотеке от GitHub - Twig-Расширения.