Traduction 25.12
webforJ inclut un système de traduction intégré pour rechercher des chaînes localisées par clé. Le système se compose d'un résolveur de traduction qui mappe les clés au texte localisé, d'une interface de préoccupation HasTranslation qui fournit une méthode pratique t(), d'App.getTranslation() pour un accès direct partout, d'une détection automatique de la langue à partir du navigateur, et d'un support pour des sources de traduction personnalisées telles que des bases de données.
The webforj-localizing-apps skill can add multi-language support and translate component labels. After installing the webforJ AI plugin, ask your assistant:
- "Add multi-language support with English and Spanish."
- "Detect the user's browser locale and apply it on startup."
- "Move all hardcoded strings into a messages bundle."
Résolveur de traduction
Le résolveur de traduction est le système qui recherche des chaînes localisées pour une clé et une langue données. webforJ fournit un résolveur par défaut, BundleTranslationResolver, qui charge les traductions à partir des fichiers de propriétés Java ResourceBundle dans le chemin de classe. Cela fonctionne dès la configuration sans dépendances supplémentaires.
Fichiers de bundle de ressources
Placez vos fichiers de traduction dans le répertoire src/main/resources. Le résolveur par défaut recherche des fichiers nommés messages avec des suffixes de langue suivant la convention de nommage standard Java ResourceBundle :
messages.properties # Traductions par défaut/de secours
messages_en.properties # Anglais
messages_de.properties # Allemand
messages_fr_CA.properties # Français (Canada)
Chaque fichier contient des paires clé-valeur. Les clés sont des identifiants que vous utilisez dans le code et les valeurs sont les chaînes traduites. Vous pouvez inclure des espaces réservés MessageFormat comme {0}, {1} pour des valeurs dynamiques :
app.title=Boîte aux lettres
menu.inbox=Boîte de réception
menu.outbox=Boîte d'envoi
greeting=Bonjour {0}, vous avez {1} nouveaux messages
app.title=Postfach
menu.inbox=Posteingang
menu.outbox=Postausgang
greeting=Hallo {0}, Sie haben {1} neue Nachrichten
Le résolveur délègue à la chaîne de résolution standard de ResourceBundle de Java, qui gère automatiquement la correspondance des langues et les substitutions.
Configuration des langues prises en charge
Le paramètre supported-locales indique à webforJ quelles langues votre application prend en charge. Cette liste est utilisée par la détection automatique pour faire correspondre la langue du navigateur de l'utilisateur aux traductions disponibles. La première langue de la liste est utilisée comme valeur de secours par défaut lorsque aucune meilleure correspondance n'est trouvée. La clé de propriété est webforj.i18n.supported-locales et accepte une liste de balises de langue BCP 47, par exemple en, de.
Consultez la section Configuration pour apprendre comment définir des propriétés pour différents environnements.
La méthode t()
Les composants qui implémentent l'interface de préoccupation HasTranslation ont accès à la méthode t() pour traduire du texte. La méthode prend une clé de traduction et renvoie la chaîne localisée pour la langue actuelle de l'application :
public class MainLayout extends Composite<AppLayout> implements HasTranslation {
public MainLayout() {
// Traduction simple
String title = t("app.title");
// Traduction avec des paramètres MessageFormat
String greeting = t("greeting", userName, messageCount);
// Traduction pour une langue spécifique
String germanTitle = t(Locale.GERMAN, "app.title");
}
}
Vous pouvez également utiliser App.getTranslation() directement partout sans implémenter l'interface :
String title = App.getTranslation("app.title");
Si une clé de traduction n'est pas trouvée, t() renvoie la clé elle-même plutôt que de lancer une exception. Cela signifie que votre application ne se bloque pas si une traduction est manquante. La clé est affichée telle quelle, et un avertissement est enregistré afin que vous puissiez suivre les traductions manquantes pendant le développement.
Implémentation de composants traduits
Un composant traduit combine généralement HasTranslation avec LocaleObserver. Utilisez t() lors de la création d'éléments d'interface utilisateur pour définir le texte traduit initial. Pour supporter le changement de langue à l'exécution, implémentez LocaleObserver et mettez à jour le même texte dans onLocaleChange().
@Route
public class MainLayout extends Composite<AppLayout>
implements HasTranslation, LocaleObserver {
private final AppLayout self = getBoundComponent();
private AppNavItem inboxItem;
private AppNavItem outboxItem;
public MainLayout() {
inboxItem = new AppNavItem(t("menu.inbox"), InboxView.class, TablerIcon.create("inbox"));
outboxItem = new AppNavItem(t("menu.outbox"), OutboxView.class, TablerIcon.create("send-2"));
AppNav appNav = new AppNav();
appNav.addItem(inboxItem);
appNav.addItem(outboxItem);
self.addToDrawer(appNav);
}
@Override
public void onLocaleChange(LocaleEvent event) {
inboxItem.setText(t("menu.inbox"));
outboxItem.setText(t("menu.outbox"));
}
}
Le système de liaison de données prend en charge les messages de validation et de transformation traduits à l'aide de Supplier<String> avec t(). Consultez les messages de validation dynamiques, messages de transformation dynamiques, et validation Jakarta sensible à la langue.
Résolveurs de traduction personnalisés
Le résolveur par défaut charge les traductions à partir des fichiers de propriétés Java ResourceBundle. Pour charger des traductions à partir d'une source différente, comme une base de données ou un service distant, implémentez TranslationResolver :
public class DatabaseTranslationResolver implements TranslationResolver {
private final TranslationRepository repository;
private final List<Locale> supportedLocales;
public DatabaseTranslationResolver(TranslationRepository repository,
List<Locale> supportedLocales) {
this.repository = repository;
this.supportedLocales = List.copyOf(supportedLocales);
}
@Override
public String resolve(String key, Locale locale, Object... args) {
String value = repository
.findByKeyAndLocale(key, locale.getLanguage())
.map(Translation::getValue)
.orElse(key);
if (args != null && args.length > 0) {
value = new MessageFormat(value, locale).format(args);
}
return value;
}
@Override
public List<Locale> getSupportedLocales() {
return supportedLocales;
}
}
Enregistrement d'un résolveur personnalisé
Dans une application webforJ classique, configurez le résolveur avant le démarrage de l'application, par exemple en utilisant un écouteur de cycle de vie de l'application :
App.setTranslationResolver(new DatabaseTranslationResolver(repository, supportedLocales));
Dans une application Spring Boot, exposez le résolveur en tant que bean :
@Configuration
public class MessageSourceConfig {
@Bean
TranslationResolver translationResolver(TranslationRepository repository,
SpringConfigurationProperties properties) {
List<Locale> supportedLocales = properties.getI18n().getSupportedLocales().stream()
.map(Locale::forLanguageTag)
.toList();
return new DatabaseTranslationResolver(repository, supportedLocales);
}
}
Lorsqu'aucun bean TranslationResolver personnalisé n'est défini, la configuration automatique de Spring fournit un BundleTranslationResolver par défaut configuré avec les langues prises en charge du fichier application.properties.