@@ -649,6 +649,172 @@ The translation of database content should be handled by Doctrine through
649649the `Translatable Extension `_ or the `Translatable Bahavior `_ (PHP 5.4+).
650650For more information, see the documentation for thes libraries.
651651
652+ Debugging Translations
653+ ----------------------
654+
655+ .. versionadded :: 2.5
656+ The ``translation:debug `` command was introduced in Symfony 2.5.
657+
658+ When maintaining a bundle, you may use or remove the usage of a translation
659+ message without updating all message catalogues. The ``translation:debug ``
660+ command helps you to find these missing or unused translation messages for a
661+ given locale. It shows you a table with the result when translating the
662+ message in the given locale and the result when the fallback would be used.
663+ On top of that, it also shows you when the translation is the same as the
664+ fallback translation (this could indicate that the message was not correctly
665+ translated).
666+
667+ Thanks to the messages extractors, the command will detect the translation
668+ tag or filter usages in Twig templates:
669+
670+ .. code-block :: jinja
671+
672+ {% trans %}Symfony2 is great{% endtrans %}
673+
674+ {{ 'Symfony2 is great'|trans }}
675+
676+ {{ 'Symfony2 is great'|transchoice(1) }}
677+
678+ {% transchoice 1 %}Symfony2 is great{% endtranschoice %}
679+
680+ It will also detect the following translator usages in PHP templates:
681+
682+ .. code-block :: php
683+
684+ $view['translator']->trans("Symfony2 is great");
685+
686+ $view['translator']->trans('Symfony2 is great');
687+
688+ .. caution ::
689+
690+ The extractors are not able to inspect the messages translated outside templates which means
691+ that translator usages in form labels or inside your controllers won't be detected.
692+ Dynamic translations involving variables or expressions are not detected in templates,
693+ which means this example won't be analyzed:
694+
695+ .. code-block :: jinja
696+ {% set message = 'Symfony2 is great' %}
697+ {{ message|trans }}
698+
699+ Suppose your application's default_locale is ``fr `` and you have configured ``en `` as the fallback locale
700+ (see :ref: `book-translation-configuration ` and :ref: `book-translation-fallback ` for how to configure these).
701+ And suppose you've already setup some translations for the ``fr `` locale inside an AcmeDemoBundle:
702+
703+ .. configuration-block ::
704+
705+ .. code-block :: xml
706+
707+ <!-- src/Acme/AcmeDemoBundle/Resources/translations/messages.fr.xliff -->
708+ <?xml version =" 1.0" ?>
709+ <xliff version =" 1.2" xmlns =" urn:oasis:names:tc:xliff:document:1.2" >
710+ <file source-language =" en" datatype =" plaintext" original =" file.ext" >
711+ <body >
712+ <trans-unit id =" 1" >
713+ <source >Symfony2 is great</source >
714+ <target >J'aime Symfony2</target >
715+ </trans-unit >
716+ </body >
717+ </file >
718+ </xliff >
719+
720+ .. code-block :: php
721+
722+ // src/Acme/AcmeDemoBundle/Resources/translations/messages.fr.php
723+ return array(
724+ 'Symfony2 is great' => 'J\'aime Symfony2',
725+ );
726+
727+ .. code-block :: yaml
728+
729+ # src/Acme/AcmeDemoBundle/Resources/translations/messages.fr.yml
730+ Symfony2 is great : J'aime Symfony2
731+
732+ and for the ``en `` locale:
733+
734+ .. configuration-block ::
735+
736+ .. code-block :: xml
737+
738+ <!-- src/Acme/AcmeDemoBundle/Resources/translations/messages.en.xliff -->
739+ <?xml version =" 1.0" ?>
740+ <xliff version =" 1.2" xmlns =" urn:oasis:names:tc:xliff:document:1.2" >
741+ <file source-language =" en" datatype =" plaintext" original =" file.ext" >
742+ <body >
743+ <trans-unit id =" 1" >
744+ <source >Symfony2 is great</source >
745+ <target >Symfony2 is great</target >
746+ </trans-unit >
747+ </body >
748+ </file >
749+ </xliff >
750+
751+ .. code-block :: php
752+
753+ // src/Acme/AcmeDemoBundle/Resources/translations/messages.en.php
754+ return array(
755+ 'Symfony2 is great' => 'Symfony2 is great',
756+ );
757+
758+ .. code-block :: yaml
759+
760+ # src/Acme/AcmeDemoBundle/Resources/translations/messages.en.yml
761+ Symfony2 is great : Symfony2 is great
762+
763+ To inspect all messages in the ``fr `` locale for the AcmeDemoBundle, run:
764+
765+ .. code-block :: bash
766+
767+ $ php app/console translation:debug fr AcmeDemoBundle
768+
769+ You will get this output:
770+
771+ .. image :: /images/book/translation/debug_1.png
772+ :align: center
773+
774+ It indicates that the message ``Symfony2 is great `` is unused because it is translated,
775+ but you haven't used it anywhere yet.
776+
777+ Now, if you translate the message in one of your templates, you will get this output:
778+
779+ .. image :: /images/book/translation/debug_2.png
780+ :align: center
781+
782+ The state is empty which means the message is translated in the ``fr `` locale and used in one or more templates.
783+
784+ If you delete the message ``Symfony2 is great `` from your translation file for the ``fr `` locale
785+ and run the command, you will get:
786+
787+ .. image :: /images/book/translation/debug_3.png
788+ :align: center
789+
790+ The state indicates the message is missing because it is not translated in the ``fr `` locale
791+ but it is still used in the template.
792+ Moreover, the message in the ``fr `` locale equals to the message in the ``en `` locale.
793+ This is a special case because the untranslated message id equals its translation in the ``en `` locale.
794+
795+ If you copy the content of the translation file in the ``en `` locale, to the translation file
796+ in the ``fr `` locale and run the command, you will get:
797+
798+ .. image :: /images/book/translation/debug_4.png
799+ :align: center
800+
801+ You can see that the translations of the message are identical in the ``fr `` and ``en `` locales
802+ which means this message was probably copied from French to English and maybe you forgot to translate it.
803+
804+ By default all domains are inspected, but it is possible to specify a single domain:
805+
806+ .. code-block :: bash
807+
808+ $ php app/console translation:debug en AcmeDemoBundle --domain=messages
809+
810+ When bundles have a lot of messages, it is useful to display only the unused
811+ or only the missing messages, by using the ``--only-unused `` or ``--only-missing `` switches:
812+
813+ .. code-block :: bash
814+
815+ $ php app/console translation:debug en AcmeDemoBundle --only-unused
816+ $ php app/console translation:debug en AcmeDemoBundle --only-missing
817+
652818 Summary
653819-------
654820
0 commit comments