Skip to content

[Translation] Add support for calling 'trans' with ICU formatted messages #37371

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

Merged
merged 1 commit into from
Aug 30, 2020

Conversation

someonewithpc
Copy link
Contributor

@someonewithpc someonewithpc commented Jun 21, 2020

Q A
Branch? master
Bug fix? maybe, see #37228
New feature? yes
Deprecations? no
Tickets Fix #37228
License MIT
Doc PR symfony/symfony-docs#13875

Motivation:

$apples = [0 => 'No apples', 1 => '1 apple', '# apples'];
echo _m($apples, ['count' => 0]); // Outputs 'No apples'
echo _m($apples, ['count' => 2]); // Outputs '2 apples'

where _m is a wrapper my application is using, but we obviously don't want to replicate many of the effort of the translation component, so it relies on trans.

This wrapper itself could be integrated into Symfony, if deemed appropriate.

See #37228

@someonewithpc
Copy link
Contributor Author

someonewithpc commented Jun 21, 2020

The AppVeyor failure doesn't seem to be related to this change, outputting: Cannot parse message translation: please install the "intl" PHP extension.

I ran the tests locally and they fail for something unrelated and caching tests. I'm not sure why these last fail, so I'd appreciate some help.

@nicolas-grekas
Copy link
Member

nicolas-grekas commented Jun 28, 2020

Cannot parse message translation: please install the "intl" PHP extension

this is totally related - and we're apparently missing some tests that should highlight that this changes the default behavior.

This looks like a BC break to me. It also forces installing the intl extension by default.
Why don't you change the default domain in you case?

@someonewithpc
Copy link
Contributor Author

someonewithpc commented Jun 28, 2020

Cannot parse message translation: please install the "intl" PHP extension

this is totally related - and we're apparently missing some tests that should highlight that this changes the default behavior.

This looks like a BC break to me. It also forces installing the intl extension by default.
Why don't you change the default domain in you case?

Unless I'm misunderstanding something, I did change the default and it doesn't do what I need, since it checks if it contains it with the domain + suffix and then gets it with only the domain, therefore whether I set my domain to have the suffix or not, it doesn't do what I need.

I see the problem of requiring the intl extension, how could I make it be a setting, or something?

https://github.com/symfony/symfony/pull/37371/files#diff-3126bfacb25e1e304b8cc720e8527a19R219
This line is what I need, essentially, it just seemed to make sense to also change the other part.

Shouldn't it be:

if ($this->hasIntlFormatter && $catalogue->defines($id, $domain))

i.e., without appending the suffix?

@nicolas-grekas
Copy link
Member

My previous comment was confusing. The existing code reads as:
if ($this->hasIntlFormatter && $catalogue->defines($id, $domain.MessageCatalogue::INTL_DOMAIN_SUFFIX)) {

This means that the catalog needs to be named with the intl+icu suffix.
Then having the intl extension will use the intl format.

@someonewithpc
Copy link
Contributor Author

Okay... But I have the intl extension enabled and I can't pass icu strings directly to trans, it seems to only work for id messages which are then defined in a file. Is it that I just need to dump the translations to a file? (since, again, I'm using a different system)

@stof
Copy link
Member

stof commented Jun 30, 2020

@someonewithpc they are not forced to come from a file. You could build custom loaders using different sources (core loaders are all about files, indeed).

@someonewithpc
Copy link
Contributor Author

someonewithpc commented Jun 30, 2020

@stof No, but I don't want a loader, I don't think. Can you check the linked issue above?

@wouterj
Copy link
Member

wouterj commented Jun 30, 2020

In this issue, you describe you want to use the Translator component like this:

$translator->trans('{{count}, plural, =1 {1 apple} other {{count} apples}}', ['{count}' => 2])

This has nothing to do with translation. It's pure message formatting. That's not what the Translation component is created for. Instead, use Intl's MessageFormatter directly:

MessageFormatter::formatMessage("en_US", "{{count}, plural, =1 {1 apple} other {{count} apples}}", ['count' => 2]);

@someonewithpc
Copy link
Contributor Author

someonewithpc commented Jun 30, 2020

@wouterj It has everything to do with translation. I still want it to translate into different languages

Like I mention in the motivation section above, the point is that _m converts from a way that is easy to specify to the ICU format

@wouterj
Copy link
Member

wouterj commented Jun 30, 2020

If you want to translate it, you'll have translation files like:

# translations/messages+intl-icu.en.yaml
apples_count: {{count}, plural, =1 {1 apple} other {{count} apples}}

And then use it as:

$translator->trans('apples_count', ['count' => 2], 'messages'); // 3rd argument not needed as "messages" is the default

@someonewithpc
Copy link
Contributor Author

@wouterj That's the point, I don't want to use ids, I want to use it like I showed above.

@someonewithpc
Copy link
Contributor Author

I updated the code and the relevant tests seem to pass. Could this get merged, or should I create a separate function?

Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works for me this way. Can you please add some tests?

if ($this->hasIntlFormatter && $catalogue->defines($id, $domain.MessageCatalogue::INTL_DOMAIN_SUFFIX)) {
if ($this->hasIntlFormatter
&& ($catalogue->defines($id, $domain.MessageCatalogue::INTL_DOMAIN_SUFFIX)
|| false != strstr($domain, MessageCatalogue::INTL_DOMAIN_SUFFIX))) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of using strstr(), I'd suggest using substr_compare() with a negative offset

@nicolas-grekas nicolas-grekas changed the title Add support for calling 'trans' with ICU formatted messages [Translator] Add support for calling 'trans' with ICU formatted messages Aug 26, 2020
@nicolas-grekas nicolas-grekas changed the title [Translator] Add support for calling 'trans' with ICU formatted messages [Translation] Add support for calling 'trans' with ICU formatted messages Aug 26, 2020
@someonewithpc someonewithpc force-pushed the master branch 2 times, most recently from 0d88759 to 9788dee Compare August 26, 2020 11:04
@fabpot
Copy link
Member

fabpot commented Aug 30, 2020

Thank you @someonewithpc.

@fabpot fabpot merged commit 241af80 into symfony:master Aug 30, 2020
@nicolas-grekas nicolas-grekas modified the milestones: next, 5.2 Oct 5, 2020
@fabpot fabpot mentioned this pull request Oct 5, 2020
javiereguiluz added a commit to symfony/symfony-docs that referenced this pull request Dec 22, 2020
…ICU formatted messages (someonewithpc)

This PR was merged into the 5.2 branch.

Discussion
----------

[Translation] Document support for calling 'trans' with ICU formatted messages

See symfony/symfony#37371

Commits
-------

a490d10 Add documentation for pull #37371
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Messages in ICU format are not handled
6 participants