Search code examples
symfonymachine-translation

How use labels in transchoice()


I need to translate a french phrase depending of gender and quantity. In message.fr.yml, I have :

key.toto: "male_singular: tu es venu 1 fois donc 1 vie|female_singular: tu es venue 1 fois donc 1 vie|male_plural: tu es venu %count% fois donc %count% vies|male_singular: tu es venue %count% fois donc %count% vies"

I see in doc of Symfony\Component\Translation\MessageSelector used by transchoice()

The indexed solution can also contain labels (e.g. one: There is one apple).

This is purely for making the translations more clear - it does not affect the functionality.

The two methods can also be mixed:

{0} There are no apples|one: There is one apple|more: There are %count% apples

But when I call transchoice With a call like that

transchoice("key.toto", "female_singular", array(), "messages")

I have :

"tu es venu 1 fois donc 1 vie"

instead of :

"tu es venue 1 fois donc 1 vie"

I prefer use labels instead of {} because messages files are translated by another enterprise.

Any idea ?


Solution

  • From Translation component documentation:

    The tags are really only hints for translators and don't affect the logic used to determine which plural form to use.

    and

    As tags are optional, the translator doesn't use them (the translator will only get a string based on its position in the string).

    You can make sure if you open the source code of transChoice() method:

    public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null)
    {
        ...
    
        return strtr($this->selector->choose($catalogue->get($id, $domain), (int) $number, $locale), $parameters);
    }
    

    As you can see, transChoice() casts the $number parameter to int.

    Manual says that PHPconverts "female_singular" to 0:

    <?php
    
    echo (int) "female_singular"; //0
    

    So when you do not specify the range in your transchoice string, Translation component make its choice based on the string position.

    In your case(number = 0) it's the string: "tu es venu 1 fois donc 1 vie".