Tobias Nyholm Abdellatif Ait boudad
Contributed by Tobias Nyholm and Abdellatif Ait boudad in #27399

The Symfony Translation component provides tools to internationalize your PHP applications. One of those tools is the transChoice() method to select a translation based on a number, which is ideal for taking care of pluralization.

However, that method uses a proprietary format to define the translations and it doesn't allow to select messages based on other conditions (for example the gender of a person).

Meanwhile, the MessageFormat created by the ICU project is a standard used in lots of applications and supports many more features. That's why Symfony 4.2 introduces an IntlFormatter class as a better replacement of transChoice().

The full MessageFormat format guide is intimidating at first because of all the features it supports. The following example selects the translation based on the gender and a number:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
use Symfony\Component\Translation\Formatter\IntlFormatter;

$translation = <<<'_TRANSLATION_'
{gender_of_host, select,
  female {{num_guests, plural, offset:1
      =0 {{host} does not give a party.}
      =1 {{host} invites {guest} to her party.}
      =2 {{host} invites {guest} and one other person to her party.}
     other {{host} invites {guest} as one of the # people invited to her party.}}}
  male   {{num_guests, plural, offset:1
      =0 {{host} does not give a party.}
      =1 {{host} invites {guest} to his party.}
      =2 {{host} invites {guest} and one other person to his party.}
     other {{host} invites {guest} as one of the # people invited to his party.}}}
  other {{num_guests, plural, offset:1
      =0 {{host} does not give a party.}
      =1 {{host} invites {guest} to their party.}
      =2 {{host} invites {guest} and one other person to their party.}
     other {{host} invites {guest} as one of the # people invited to their party.}}}}
_TRANSLATION_;

$message = (new IntlFormatter())->formatIntl($translation, 'en', [
    'gender_of_host' => 'male',
    'num_guests' => 10,
    'host' => 'Jon',
    'guest' => 'Jane',
]);
// $message = 'Jon invites Jane as one of the 9 people invited to his party.'

In Symfony applications, this new formatter is enabled explicitly based on the name of your translation files. Specifically, add the +intl-icu suffix if you want the translation file to be processed with this new formatter. For example, messages.en.xlf uses the old formatter and messages+intl-icu.en.xlf uses the new formatter.

Lastly, the new formatter also deprecates the transChoice() method, which is replaced by the trans() method with a parameter called %count%.

Published in #Living on the edge