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%
.
Awesome!!!
This is great news!
If you need ICU translations but cannot wait for/update to Symfony 4.2, you may want to have a look at https://github.com/webfactory/WebfactoryIcuTranslationBundle .