Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom trans filter in Twig and Symfony2

I need to override the standard Twig trans filter for my own purposes, i.e I want to get my translations from a custom storage. I tried to figure it out in the docs. But there is no details about translations. I found the Symfony\Bridge\Twig\Extension\TranslationExtension class and I think that I only need to override this class? Thanks in advance!

like image 936
nowiko Avatar asked Jan 23 '15 10:01

nowiko


2 Answers

Just to expand on @Webberig's answer above, in Symphony v3.0.4 and Twig v1.24.0, the way you define your service seems important.

I wanted to add a domain fallback capability to the default trans() filter but couldn't figure out how to override the default filter. I finally succeeded like so:

In app/config/services.yml

# This is important!! Use this exact service ID (twig.extension.trans)
twig.extension.trans:
  class: AppBundle\Twig\AppTranslationExtension
  public: false
  arguments: ['@translator']
  tags:
    - { name: twig.extension }

And that's what basically did it for me: using the same exact service ID in my config.

For the rest I just overrided the trans filter method. Here it is for those interested:

namespace AppBundle\Twig;

use Symfony\Bridge\Twig\Extension\TranslationExtension;
use Symfony\Component\Translation\TranslatorInterface;

class AppTranslationExtension extends TranslationExtension
{
    public function __construct(
            TranslatorInterface $translator, 
            \Twig_NodeVisitorInterface $translationNodeVisitor = null)
    {
        parent::__construct($translator, $translationNodeVisitor);
    }

    /**
     * {@inheritdoc}
     */
    public function getFilters()
    {
        return array(
            new \Twig_SimpleFilter('trans', array($this, 'trans')),
        );
    }

    public function trans($id, array $parameters = array(), $domain = null, $locale = null)
    {
        if (null === $locale) {
            $locale = $this->getTranslator()->getLocale();
        }

        if (null === $domain) {
            $domain = 'messages';
        }

        if ('messages' !== $domain 
        && false === $this->translationExists($id, $domain, $locale)) {
            $domain = 'messages';
        }

        return $this->getTranslator()->trans($id, $parameters, $domain, $locale);
    }

    protected function translationExists($id, $domain, $locale)
    {
        return $this->getTranslator()->getCatalogue($locale)->has((string) $id, $domain);
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return 'app_translator';
    }
}
like image 196
peamak Avatar answered Sep 29 '22 13:09

peamak


The Translations component of Symfony basically overrides Twig's default trans filter. The component is part of the core frameworkBundle and can't be disabled.

You can however do the same and re-override the trans filter with your own Twig extension.

Just create a Twig extension as described here: http://symfony.com/doc/current/cookbook/templating/twig_extension.html

If you add a trans filter, it will override the Translation component's code.

like image 37
Webberig Avatar answered Sep 29 '22 11:09

Webberig