New in Symfony 4.2: IntlMessageFormatter

Warning: This post is about an unsupported Symfony version. Some of this information may be out of date. Read the most recent Symfony Docs.
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%
.
Help the Symfony project!
As with any Open-Source project, contributing code or documentation is the most common way to help, but we also have a wide range of sponsoring opportunities.
Comments
Comments are closed.
To ensure that comments stay relevant, they are closed for old posts.
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 .