flow
flow copied to clipboard
Add an alternative API for getTranslation
Describe your motivation
The current getTranslation
API is convenient when used inside a parent layout because it's inherited from Component
. However, if you need to get a translation for a key somewhere where this API isn't inherited there aren't convenient options available. One such case is a static factory method for creating components:
private static TextField createField() {
return new TextField("Your name");
}
In this scenario, you could access the getTranslation
API, for example, via VaadinService.getCurrent().getInstantiator().getI18NProvider()
but a helper method would be required to avoid verbosity.
Another approach could be not setting the field's label in the constructor and using the instance itself to access getTranslation
.
var field = new TextField();
field.setLabel(field.getTranslation("yourname.label"));
However, this method requires referencing a component instance, even though obtaining a localized string isn't a task inherently tied to a specific instance.
Describe the solution you'd like
Introduce a method for obtaining translations through an API not bound to a component instance but available universally.
I don't have a well-thought-out API suggestion at this time, but perhaps a static method would work here, so the usage could be similar to that of @vaadin/hilla-react-i18n
:
import static com.vaadin.flow.i18n.I18NProvider.translate;
...
private static TextField createField() {
return new TextField(translate("yourname.label"));
}
Additional context
The absence of such an API poses challenges with the Copilot i18n plugin, which automatically transforms static strings to getTranslate
calls. Since it's not context-aware, in the worst-case scenario, it might produce a view class that doesn't compile. See the workaround under consideration for more details.
Alternative suggestion: Add a constructor/methods that takes in some kind of custom class e.g. "Translateable(String template, Object...)" so that the components can translate it on demand.
private static TextField createField(User user) {
return new TextField(Translatable.of("yourname.label", user.getName()));
}
I suggest to add two new static methods in I18NProvider
interface:
static String translate(String key, Object... params)
static String translate(String key, Locale locale, Object... params)
These methods would only work within an active Vaadin service. Without it, these would either throw exception or return empty String.
In addition, in some future version there could be also new type like Translateable, it could contain at minimum a key. Optionally also array of Object params and Locale object. Adding one would mean that i18n API needs new set of methods that supports the new type. And later components could be updated to fully support it.