-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Translation] Added intl message formatter. #27399
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
*/ | ||
public function format($message, $locale, array $parameters = array()) | ||
{ | ||
$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.
When the parsing of this message fails you get a very non-descriptive exception message (Constructor failed
). Might be good for DX to rethrow a more descriptive one.
*/ | ||
private function getFormatter(string $domain) | ||
{ | ||
if (isset($this->formatters[$domain])) { |
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.
this could be reduced to:
return $this->formatters[$domain] ?? $this->formatters['_default'];
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.
And we can declare return type also
|
||
public function testFormatWithNamedArguments() | ||
{ | ||
if (PHP_VERSION_ID < 50500 || version_compare(INTL_ICU_VERSION, '4.8', '<')) { |
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.
Checking for php version is redundant
Line 19 in f557f94
"php": "^7.1.3", |
I've rebased this PR and updated according to feedback. |
@@ -132,6 +132,15 @@ public function addResource($format, $resource, $locale, $domain = null) | |||
} | |||
} | |||
|
|||
/** | |||
* @param string $domain | |||
* @param MessageFormatterInterface $formatter |
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.
to be removed :)
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.
Thank you. I added : void
as return type.
/** | ||
* @param string $domain | ||
* | ||
* @return MessageFormatterInterface |
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.
to be removed (and a real return type be used instead)
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.
Thank you
Anything I can do to help review this? |
Love the change and allowing to get rid of special case of transChoice (over time). The original PR mentioned something about storing format with the messages and I actually tend to agree with it. The format IS information that's directly coupled with actual messages (basically, a meta information about contents of the file). This becomes even more important if translations are coming from external source and are not part of source files. There already have been talks about allowing different caching mechanisms and sources (like database) so coupling domain to format in config would not allow for changes in message format without deployment (and would make syncing changes hard anyway). |
Added to project "Contracts" after comment #28210 (comment) |
*/ | ||
public function choiceFormat($message, $number, $locale, array $parameters = array()) | ||
{ | ||
return $this->format($message, $locale, $parameters); |
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.
Is this kind of implementation right? Argument number
is unused.
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 think we shouldn't implement the ChoiceMessageFormatterInterface
instead, it will disallow using the transChoice
method which is right since we should only use the trans
method for intl-formated message.
} catch (\Throwable $e) { | ||
throw new \InvalidArgumentException('Invalid message format.', $e); | ||
} | ||
if (null === $formatter) { |
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.
It will never be null here
I like it, but I would make the new formatter accessible only through |
Some description of the format here: |
7358b74
to
daaceb0
Compare
daaceb0
to
597a15d
Compare
I've updated this PR. With the fallback formatter we can support both "Symfony style plural" and intl messages at the same time. This will make sure we have a zero config solution for adding support for this new feature while all the old formats still works as expected. Possible update: I could make the |
if (!\extension_loaded('intl')) { | ||
$this->markTestSkipped( | ||
'The Intl extension is not available.' | ||
); |
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 be on one line
|
||
class IntlMessageFormatterTest extends \PHPUnit\Framework\TestCase | ||
{ | ||
public function setUp() |
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 be protected
); | ||
} | ||
|
||
private function getMessageFormatter() |
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 think this can be inlined instead.
@@ -7,6 +7,7 @@ CHANGELOG | |||
* Started using ICU parent locales as fallback locales. | |||
* deprecated `TranslatorInterface` in favor of `Symfony\Contracts\Translation\TranslatorInterface` | |||
* deprecated `MessageSelector`, `Interval` and `PluralizationRules`; use `IdentityTranslator` instead | |||
* Added `IntlMessageFormatter` and`FallbackMessageFormatter` |
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.
missing space after and
.
* file that was distributed with this source code. | ||
*/ | ||
|
||
declare(strict_types=1); |
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.
AFAIK, we are not using this anywhere else, this should be removed.
return $this->secondFormatter->choiceFormat($message, $number, $locale, $parameters); | ||
} | ||
|
||
throw new LogicException(sprintf('The no formatter support plural translations.')); |
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.
The message is not so clear to me :) I suppose you meant No formatters support plural translations.
try { | ||
$formatter = new \MessageFormatter($locale, $message); | ||
} catch (\Throwable $e) { | ||
throw new InvalidArgumentException(sprintf('Invalid message format. Reason: %s (error #%d)', intl_get_error_message(), intl_get_error_code()), 0, $e); |
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.
As an exception should end with a dot, I suggest to use Invalid message format (%s, error #%d).
Same below
Thank you for the review, Ive updated the PR |
{ | ||
try { | ||
$result = $this->firstFormatter->format($message, $locale, $parameters); | ||
} catch (\Throwable $e) { |
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.
Can we be more specific here? We should be as much as possible IMHO (same below.)
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.
Do we want to be more specific?
I know the IntlMesaageFormatter only throws InvalidArgument, but isn’t it a good idea to catch everything to give the second formatter a change to run?
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 agree with @nicolas-grekas
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.
With one small comment. In a followup PR, we should deprecate the old way, deprecate transChoice
and probably try to write a script that converts our proprietary format to the intl one. WDYT?
@@ -17,6 +17,7 @@ | |||
use Symfony\Component\Translation\Formatter\FallbackFormatter; | |||
use Symfony\Component\Translation\Formatter\MessageFormatterInterface; | |||
|
|||
|
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 be removed
use Symfony\Component\Translation\Formatter\FallbackFormatter; | ||
use Symfony\Component\Translation\Formatter\MessageFormatterInterface; | ||
|
||
|
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 be reverted
💯 for both! |
Thank you. PR updated. I agree to deprecate transChoice |
Thank you @Nyholm. |
…, Nyholm) This PR was merged into the 4.2-dev branch. Discussion ---------- [Translation] Added intl message formatter. | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | replaces #20007 | License | MIT | Doc PR | This PR will replace #20007 and continue the work from the original author. I've have tried to address all comments made in the original PR. Commits ------- 2a90931 cs fb30c77 Be more specific with what exception we catch b1aa004 Only use the default translator if intl extension is loaded f88153f Updates according to feedback 597a15d Use FallbackFormatter instead of support for multiple formatters 2aa7181 Fixes according to feedback a325a44 Allow config for different domain specific formatters b43fe21 Add support for multiple formatters c2b3dc0 [Translation] Added intl message formatter. 19e8e69 use error 940d440 Make it a warning
…from contracts (Nyholm, nicolas-grekas) This PR was merged into the 4.2-dev branch. Discussion ---------- [Translator] Deprecated transChoice and moved it away from contracts | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | no | BC breaks? | no | Deprecations? | yes | Tests pass? | yes | Fixed tickets | n/a | License | MIT | Doc PR | Issue: symfony/symfony-docs#10264 This will address comment made here: #27399 (review) This PR moves the `transChoice()` method away from Contracts and back to the component. I also reverted changes in the `IdentityTranslator`. I will still use the deprecated `MessageSelector` but this is not fine since `transChoice()` is also deprecated. Commits ------- dc5f3bf Make trans + %count% parameter resolve plurals d870a85 [Translator] Deprecated transChoice and moved it away from contracts
This PR will replace #20007 and continue the work from the original author.
I've have tried to address all comments made in the original PR.