Skip to content
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

Add an alternative API for getTranslation #19333

Open
tomivirkki opened this issue May 8, 2024 · 2 comments
Open

Add an alternative API for getTranslation #19333

tomivirkki opened this issue May 8, 2024 · 2 comments

Comments

@tomivirkki
Copy link
Member

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.

@knoobie
Copy link
Contributor

knoobie commented May 8, 2024

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()));
}

@tltv
Copy link
Member

tltv commented May 24, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: 🟢Ready to Go
Development

No branches or pull requests

4 participants