-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Translation] allow using the ICU message format using domains with the "+intl-icu" suffix #28952
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
5c0f147
to
a4fb360
Compare
There is one downside to this compared to the |
|
a4fb360
to
6e544b4
Compare
The current proposal (adding |
6e544b4
to
1e9b58d
Compare
nothing I can think of: a |
This requires updating all places using the translator to use an explicit domain though, making the migrating painful. |
the question of course would be: what is the way for loaders to decide whether the resource they load is using the Intl-ICU format or the Symfony one ? |
hmm, actually, looking at the implementation, the |
Yes! Sorry if that wasn't clear. I updated the PR description. |
src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
Show resolved
Hide resolved
throw new LogicException('Cannot parse message translation: please install the "intl" PHP extension or the "symfony/polyfill-intl-messageformatter" package.'); | ||
} | ||
try { | ||
$this->cache[$locale][$message] = $formatter = new \MessageFormatter($locale, $message); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we actually memoize all the formatters ? This increases memory usage for each message being formatted. In my experience, a page is much more likely to translate lots of different messages than lots of messages being the same.
What is the benefit in terms of speed when skipping the instantiation the second time (when using the intl extension. I don't care about the performance of the polyfill here, as the way to improve performance in such case would be to install ext-intl). Does it actually justify such memory leak ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I benched this with the extension:
\MessageFormatter::formatMessage('Hello {name}', 'en', array('name' => 'Bob'));
vs
$formatter->format(array('name' => 'Bob'));
the later is 3 times faster than the former and each $formatter object takes 226 bytes.
With that in mind, I think it's worth doing it: for run-once requests we don't care, and for long-running ones, the benefit is worth it IMHO.
foreach ($parameters as $key => $value) { | ||
if ('%' === ($key[0] ?? null)) { | ||
unset($parameters[$key]); | ||
$parameters[trim($key, '%')] = $value; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we also support the {{ name }}
convention, which is used in the Validator component for instance ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good idead, updated
src/Symfony/Component/Translation/Formatter/IntlMessageFormatter.php
Outdated
Show resolved
Hide resolved
f221f4a
to
326dd08
Compare
…he "+intl-icu" suffix
326dd08
to
d95cc4d
Compare
$this->assertInstanceof(IntlFormatterInterface::class, $formatter); | ||
$this->assertSame('Hello Fab', $formatter->formatIntl('Hello {name}', 'en', array('name' => 'Fab'))); | ||
$this->assertSame('Hello Fab', $formatter->formatIntl('Hello {name}', 'en', array('%name%' => 'Fab'))); | ||
$this->assertSame('Hello Fab', $formatter->formatIntl('Hello {name}', 'en', array('{{ name }}' => 'Fab'))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice
if ($catalogue->defines($id, $domain)) { | ||
break; | ||
} | ||
if ($cat = $catalogue->getFallbackCatalogue()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we really sure this always will return null
eventually?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose: this is the exact same logic as in transChoice. Not having it here was a bug actually (with no side effects since trans wasn't locale sensitive before)
Ping @symfony/deciders |
Thank you @nicolas-grekas. |
… domains with the "+intl-icu" suffix (nicolas-grekas) This PR was merged into the 4.2-dev branch. Discussion ---------- [Translation] allow using the ICU message format using domains with the "+intl-icu" suffix | Q | A | ------------- | --- | Branch? | 4.2 | Bug fix? | no | New feature? | yes | BC breaks? | no (unless merged after 4.2) | Deprecations? | no | Tests pass? | yes | Fixed tickets | - | License | MIT | Doc PR | - This PR replaces the `FallbackFormatter` logic by explicit opt-in. This allows triggering accurate exceptions when one wants to use the ICU message format but the extension (or the polyfill) is missing. The way to opt-in is to put messages in a domain with the `+intl-icu` suffix *at loading/declaration time*. E.g. translations in `messages+intl-icu.en.yaml` will be read as part of the `messages` domain , but will be parsed by intl's `MessageFormatter` instead of the default Symfony one. To make it seamless to adopt the ICU format, `%`s are trimmed from parameter keys (idea borrowed from https://github.com/webfactory/WebfactoryIcuTranslationBundle) This is for 4.2 as it changes a feature that is not released yet. ping @Nyholm - we drafted this together. Commits ------- d95cc4d [Translation] allow using the ICU message format using domains with the "+intl-icu" suffix
This PR replaces the
FallbackFormatter
logic by explicit opt-in.This allows triggering accurate exceptions when one wants to use the ICU message format but the extension (or the polyfill) is missing.
The way to opt-in is to put messages in a domain with the
+intl-icu
suffix at loading/declaration time.E.g. translations in
messages+intl-icu.en.yaml
will be read as part of themessages
domain , but will be parsed by intl'sMessageFormatter
instead of the default Symfony one.To make it seamless to adopt the ICU format,
%
s are trimmed from parameter keys (idea borrowed from https://github.com/webfactory/WebfactoryIcuTranslationBundle)This is for 4.2 as it changes a feature that is not released yet.
ping @Nyholm - we drafted this together.