Skip to content

[Translation] Add StaticMessage #60935

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

Open
wants to merge 2 commits into
base: 7.4
Choose a base branch
from

Conversation

VincentLanglet
Copy link
Contributor

@VincentLanglet VincentLanglet commented Jun 28, 2025

Q A
Branch? 7.4
Bug fix? no
New feature? yes
Deprecations? no
Issues Fix #...
License MIT

When working with translation, it's "classic" to have library with the following logic:

if ($message instanceof Translatable) {
    $message->trans($translator);
} else {
    $translator->trans($message, domain: 'OpenSourceBundle');
}

Then if the user doesn't want the text to be translated, he cannot.

A useful and simple way would be to support new TranslatableMessage($text, domain: false) but as recommended, it might be better to introduce a special class for this, the StaticMessage

@carsonbot

This comment has been minimized.

@VincentLanglet VincentLanglet marked this pull request as ready for review June 28, 2025 07:15
@carsonbot carsonbot added this to the 7.4 milestone Jun 28, 2025
@carsonbot carsonbot changed the title Allow to use false as domain for translatableMessage [Translation] Allow to use false as domain for translatableMessage Jun 29, 2025
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.

can you please add a line in the changelog ?

@mdeboer
Copy link
Contributor

mdeboer commented Jun 29, 2025

Just out of curiosity, do you have any examples where you have a Translatable message, that shouldn't be translated?

Don't get me wrong but to me it really smells. A Translatable object should inherently be translatable. Setting the domain to false does not really tell me that it shouldn't be translated, rather I would expect a "default" domain to be used like "messages".

But maybe some examples would clear things up for me why this path was chosen.

Thanks in advance! 🙏🏻

@VincentLanglet
Copy link
Contributor Author

Setting the domain to false does not really tell me that it shouldn't be translated, rather I would expect a "default" domain to be used like "messages".

Let's just answer this point first @mdeboer, it's the purpose of the NULL domain, you can find it in a lot of "domain" options like https://symfony.com/doc/current/reference/forms/types/form.html#translation-domain

Just out of curiosity, do you have any examples where you have a Translatable message, that shouldn't be translated?

Don't get me wrong but to me it really smells. A Translatable object should inherently be translatable.

Sure, for instance EasyAdmin always translate his labels, title, flash message, and more
https://github.com/EasyCorp/EasyAdminBundle/blob/4.x/templates/flash_messages.html.twig#L12
It use messages or EasyAdminBundle as default translation domains based on the context, but support using Translatable object in order to use another domain but doesn't support disabling the translation.

Maybe the right behavior would be:

  • to not translate by default
  • to ask users to pass translatableMessage instead

but:

  • it's a big BC break
  • when 99% of labels asked to be translated it ask adding t() everywhere

I find it simpler to allow false as translation_domain for such library ; especially because it's not the first library I saw with this "translate by default"...

@OskarStark OskarStark changed the title [Translation] Allow to use false as domain for translatableMessage [Translation] Allow to use false as domain for translatableMessage Jun 29, 2025
@OskarStark OskarStark changed the title [Translation] Allow to use false as domain for translatableMessage [Translation] Allow to use false as domain for TranslatableMessage Jun 29, 2025
@mdeboer
Copy link
Contributor

mdeboer commented Jun 29, 2025

Thanks for your reply @VincentLanglet

I understand that in case of EasyAdmin it is easier to allow this change, but imho this is a design flaw in EasyAdmin. Why should the framework bend the rules and accommodate this bad design pattern?

Wouldn't something like Rector be of use to refactor EasyAdmin?

Or maybe introduce something like an UntranslatableMessage?

@VincentLanglet
Copy link
Contributor Author

VincentLanglet commented Jun 29, 2025

Thanks for your reply @VincentLanglet

I understand that in case of EasyAdmin it is easier to allow this change, but imho this is a design flaw in EasyAdmin. Why should the framework bend the rules and accommodate this bad design pattern?

Wouldn't something like Rector be of use to refactor EasyAdmin?

No, because

  • it's mainly translated in the view which are twig templates
  • such change would be an HARD BC-break

And while it could be considered as a design flaw, be aware that

  • such libs was implemented before the introduction of translatable interface
  • it could also be considered as a useful shortcut to automatically translate text when it's the case in 99%.

For instance, form labels are translated by default by Symfony, and they allow a false translation domain now, but you could use the same argument to say it shouldn't translate and wait for TranslateMessage in order to produce a translation, or you should pass the label already-translated.

Or maybe introduce something like an UntranslatableMessage?

Might be better indeed
I update the PR with a NonTranslatableMessage @mdeboer

(cc @nicolas-grekas if you want to re-review since the whole PR changed).

@VincentLanglet VincentLanglet changed the title [Translation] Allow to use false as domain for TranslatableMessage [Translation] Introduce UntranslatableMessage Jun 29, 2025
@VincentLanglet VincentLanglet changed the title [Translation] Introduce UntranslatableMessage [Translation] Introduce NonTranslatableMessage Jun 29, 2025
Copy link
Contributor

@mdeboer mdeboer left a comment

Choose a reason for hiding this comment

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

Nice, looks good to me 👍🏻 Now it is a clear indicator that the message should not be translated and it fixes the original problem.

@OskarStark OskarStark changed the title [Translation] Introduce NonTranslatableMessage [Translation] Add NonTranslatableMessage Jun 30, 2025
@xabbuh
Copy link
Member

xabbuh commented Jun 30, 2025

I am not convinced that this really is the way to go. Having something passed around that implements an interface called TranslatableInterface which then ends up not being translated is unexpected behaviour to me. Thus I am 👎 on adding this NonTranslatableMessage class.

@VincentLanglet
Copy link
Contributor Author

I am not convinced that this really is the way to go. Having something passed around that implements an interface called TranslatableInterface which then ends up not being translated is unexpected behaviour to me. Thus I am 👎 on adding this NonTranslatableMessage class.

What alternative do you propose then for #60935 (comment) ? @xabbuh

Moreover this is still an implementation which can be done in the userland code, but it would be useful to provide it by default, in the same way symfony provides IdentityTranslator which is described with the comment:

IdentityTranslator does not translate anything.

@xabbuh
Copy link
Member

xabbuh commented Jun 30, 2025

The issue you outline in #60935 (comment) should be adressed in EasyAdminBundle and if it's simply shipping the NonTranslatableMessage class IMO.

@VincentLanglet
Copy link
Contributor Author

The issue you outline in #60935 (comment) should be adressed in EasyAdminBundle and if it's simply shipping the NonTranslatableMessage class IMO.

So instead of creating a NonTranslatableMessage in Symfony, with a really generic behavior of "Keeping the message as if even if someone try to translate it later", you recommend to add this class in every bundle with this need. That seems odd to me :/.

EasyAdminBundle is not the only one bundle with the translate by default behavior.

Seems like a classic behavior of Symfony to me when providing an interface to often

  • Give the real implementation
  • Provide a stub/fixed/basic implementation

If the NonTranslatableMessage does not makes sens, the IdentityTranslator shouldn't have a lot more.

That could also allows to simplify code for some libs when you currently have to support string|TranslatableInterface now you could only support TranslatableInterface...

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.

I'm fine with adding this personally - that's a valid implementation of the interface to me (each one their specific behavior after all).

I'm wondering about the naming: you can call trans() so technically this is translatable. It's just that the translation is fixed.

LiteralMessage? RawMessage? StaticMessage?

@VincentLanglet
Copy link
Contributor Author

LiteralMessage? RawMessage? StaticMessage?

I'm fine with all of three.
Can also be IdentityMessage (since we have an IdentityTranslator) or FixedMessage.

Any preference @nicolas-grekas ?

@stof
Copy link
Member

stof commented Jul 7, 2025

I'm also in favor of adding such an implementation in core. I have it in my work project at Incenteev since quite some time (named ConfiguredMessage as my initial use case was for messages configured by an admin user that can be used in places using translatable messages otherwise)

@OskarStark
Copy link
Contributor

I like StaticMessage, but just my 2 cents

@VincentLanglet VincentLanglet force-pushed the translatableFalse branch 2 times, most recently from c43d73d to bee320a Compare July 10, 2025 23:18
@VincentLanglet
Copy link
Contributor Author

I like StaticMessage, but just my 2 cents

I renamed it to StaticMessage then @OskarStark @nicolas-grekas

@VincentLanglet VincentLanglet changed the title [Translation] Add NonTranslatableMessage [Translation] Add StaticMessage Jul 11, 2025
@OskarStark
Copy link
Contributor

PR body would need an update

@VincentLanglet VincentLanglet requested review from xabbuh and stof July 13, 2025 09:19
nicolas-grekas added a commit that referenced this pull request Jul 17, 2025
…ng` (VincentLanglet)

This PR was squashed before being merged into the 7.4 branch.

Discussion
----------

[Translation] Deprecate `TranslatableMessage::__toString`

| Q             | A
| ------------- | ---
| Branch?       | 7.4
| Bug fix?      | no
| New feature?  | no
| Deprecations? | yes
| Issues        | Fix #... <!-- prefix each issue number with "Fix #"; no need to create an issue if none exists, explain below -->
| License       | MIT

Resolve the following discussion #60935 (comment)
cc `@stof` `@xabbuh`

Commits
-------

916befb [Translation] Deprecate `TranslatableMessage::__toString`
@VincentLanglet VincentLanglet force-pushed the translatableFalse branch 2 times, most recently from 1789d56 to 92e35ca Compare July 17, 2025 22:00
@VincentLanglet
Copy link
Contributor Author

Ready for review @xabbuh @stof

@VincentLanglet VincentLanglet requested a review from stof July 18, 2025 08:49
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.

8 participants