@@ -649,6 +649,172 @@ The translation of database content should be handled by Doctrine through
649
649
the `Translatable Extension `_ or the `Translatable Bahavior `_ (PHP 5.4+).
650
650
For more information, see the documentation for thes libraries.
651
651
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
+
652
818
Summary
653
819
-------
654
820
0 commit comments