The Symfony 2 translator does a great job at translating text but there is not a great way to quickly see what text in a project is translated, especially when it could be translated by Symfony internally, in a model file, in a controller, in a twig template, etc. Given all of the different options, how could you quickly confirm text is running through the translator, and running through the translator only one time, so you don’t end up double translating text. I needed a way to highlight translations so I could see what was getting translated so I could make sure all of my dynamic copy was running through translation at some point.

 

I came up with a simple solution of overriding the Symfony translator and wrapping the text output with {% trans %} phrase {% endtrans%} so I could visually see what text was translated. I used a parameter to turn the highlighting on/off so the highlighting wasn’t always on.

 

To begin, let’s create a new translator that extends off of the Symfony translator and save it in the src/SymfonyExtension/Bundle/FrameworkBundle/Translation/Translator directory. This is also covered in this article which covers how to override the Symfony translator to log source text to a database.

// src/SymfonyExtension/Bundle/FrameworkBundle/Translation/Translator

namespace SymfonyExtension\Bundle\FrameworkBundle\Translation;

use Symfony\Bundle\FrameworkBundle\Translation\Translator as BaseTranslator;

class Translator extends BaseTranslator {

    /**
     * trans
     *
     * @author Joe Sexton <joe@webtipblog.com>
     * {@inheritdoc}
     */
    public function trans( $id, array $parameters = array(), $domain = null, $locale = null )
    {
        return parent::trans( $id, $parameters, $domain, $locale );
    }

    /**
     * transChoice
     *
     * @author Joe Sexton <joe@webtipblog.com>
     * {@inheritdoc}
     */
    public function transChoice( $id, $number, array $parameters = array(), $domain = null, $locale = null )
    {
        return parent::transChoice( $id, $number, $parameters, $domain, $locale );
    }
}

 

Next, we need to tell Symfony to use the new translator by adding the following to the app/config/config_dev.yml file so this highlighting can only be enabled in the dev environment.

# app/parameters_dev.yml

parameters:
    translator.class: SymfonyExtension\Bundle\FrameworkBundle\Translation\Translator

Note: if you want this to work in production or only in the beta environment, then add this to parameters.yml or parameters_beta.yml.

 

At this point you should be able to clear your cache and verify that the new translator is running. If you don’t have any translations yet, simply add a die(); statement to the new translator to make sure it is working.

 

Now that the new translator class is working and translating text, simple add a parameter to enable/disable the highlighting in the parameters_dev.yml file.

# app/parameters_dev.yml

parameters:
    translator.class: SymfonyExtension\Bundle\FrameworkBundle\Translation\Translator
    translator.enable_translation_highlighting: true

 

Now, update the translator class to wrap translated phrases with the {% trans %} tags for visual indication of a translation.

// src/SymfonyExtension/Bundle/FrameworkBundle/Translation/Translator

namespace SymfonyExtension\Bundle\FrameworkBundle\Translation;

use Symfony\Bundle\FrameworkBundle\Translation\Translator as BaseTranslator;

class Translator extends BaseTranslator {

    /**
     * trans
     *
     * @author Joe Sexton <joe@webtipblog.com>
     * {@inheritdoc}
     */
    public function trans( $id, array $parameters = array(), $domain = null, $locale = null )
    {
        // highlight translated text for debug
        if ( $this->container->hasParameter( 'translator.enable_translation_highlighting' ) && $this->container->getParameter( 'translator.enable_translation_highlighting' ) == 'true' ) {

            return '{% trans %}' . parent::trans( $id, $parameters, $domain, $locale ) . '{% endtrans %}';

        } else {

            return parent::trans( $id, $parameters, $domain, $locale );
        }
    }

    /**
     * transChoice
     *
     * @author Joe Sexton <joe@webtipblog.com>
     * {@inheritdoc}
     */
    public function transChoice( $id, $number, array $parameters = array(), $domain = null, $locale = null )
    {
        // highlight translated text for debug
        if ( $this->container->hasParameter( 'translator.enable_translation_highlighting' ) && $this->container->getParameter( 'translator.enable_translation_highlighting' ) == 'true' ) {

            return '{% trans %}' . parent::transChoice( $id, $number, $parameters, $domain, $locale ) . '{% endtrans %}';

        } else {

            return parent::transChoice( $id, $number, $parameters, $domain, $locale );
        }

    }
}

 

Now, if a phrase is wrapped in twig {% trans %} tags, runs through the twig {{ var|trans }} filter, or uses the translator->trans() method in a controller or model, the output in the browser will have {% trans %} ‘tags’ wrapped around it for a visual indication of what is being translated. You could use tags with styling, but your success will vary depending on output escaping in your twig template, so I opted to use the twig {% trans %} tag in my implementation. If text is translated twice, you will see two sets of {% trans %} tags wrapped around it.