Zum Hauptinhalt springen

Translation 25.12

In ChatGPT öffnen

webforJ enthält ein eingebautes Übersetzungssystem, um lokalisierten Text anhand von Schlüsseln abzurufen. Das System besteht aus einem Übersetzungsresolver, der Schlüssel auf lokalisierten Text abbildet, einer HasTranslation Schnittstelle, die eine praktische t() Methode bereitstellt, App.getTranslation() für den direkten Zugriff überall, automatische Gebietsschilderkennung vom Browser und Unterstützung für benutzerdefinierte Übersetzungsquellen wie Datenbanken.

Übersetzungsresolver

Der Übersetzungsresolver ist das System, das lokalisierten Text für einen gegebenen Schlüssel und ein Gebietsschema sucht. webforJ bietet einen Standardresolver, BundleTranslationResolver, der Übersetzungen aus Java ResourceBundle-Eigenschaftsdateien im Klassenpfad lädt. Dies funktioniert sofort ohne zusätzliche Abhängigkeiten.

Ressourcenbündel-Dateien

Platzieren Sie Ihre Übersetzungsdateien im Verzeichnis src/main/resources. Der Standardresolver sucht nach Dateien mit dem Namen messages und Gebietsschema-Suffixen gemäß der Standard-Java ResourceBundle Benennungskonvention:

messages.properties        # Standard-/Fallback-Übersetzungen
messages_en.properties # Englisch
messages_de.properties # Deutsch
messages_fr_CA.properties # Französisch (Kanada)

Jede Datei enthält Schlüssel-Wert-Paare. Schlüssel sind Bezeichner, die Sie im Code verwenden, und Werte sind die übersetzten Strings. Sie können MessageFormat Platzhalter wie {0}, {1} für dynamische Werte einfügen:

messages.properties
app.title=Mailbox
menu.inbox=Posteingang
menu.outbox=Postausgang
greeting=Hallo {0}, Sie haben {1} neue Nachrichten
messages_de.properties
app.title=Postfach
menu.inbox=Posteingang
menu.outbox=Postausgang
greeting=Hallo {0}, Sie haben {1} neue Nachrichten

Der Resolver delegiert an die Standard ResourceBundle Auflösungsreihe von Java, die die Übereinstimmung des Gebietsschemas und die Fallbacks automatisch behandelt.

Unterstützte Gebietsstandards konfigurieren

Die Einstellung supported-locales teilt webforJ mit, welche Gebietsschemas Ihre App unterstützt. Diese Liste wird von der automatischen Erkennung verwendet, um die Gebietsschemata des Browsers des Benutzers mit verfügbaren Übersetzungen abzugleichen. Das erste Gebietsschema in der Liste wird als Standard-Fallback verwendet, wenn keine bessere Übereinstimmung gefunden wird. Der Eigenschaftsschlüssel ist webforj.i18n.supported-locales und akzeptiert eine Liste von BCP 47 Sprachbezeichnern, wie z.B. en, de.

Weitere Informationen

Siehe den Abschnitt Konfiguration, um zu erfahren, wie Sie Eigenschaften für verschiedene Umgebungen festlegen.

Die t() Methode

Komponenten, die die HasTranslation Schnittstelle implementieren, erhalten Zugriff auf die t() Methode zum Übersetzen von Text. Die Methode nimmt einen Übersetzungsschlüssel und gibt den lokalisierten String für das aktuelle App-Gebietsschema zurück:

public class MainLayout extends Composite<AppLayout> implements HasTranslation {

public MainLayout() {
// Einfache Übersetzung
String title = t("app.title");

// Übersetzung mit MessageFormat-Parametern
String greeting = t("greeting", userName, messageCount);

// Übersetzung für ein bestimmtes Gebietsschema
String germanTitle = t(Locale.GERMAN, "app.title");
}
}

Sie können auch App.getTranslation() direkt überall verwenden, ohne die Schnittstelle zu implementieren:

String title = App.getTranslation("app.title");
Sanfter Fallback

Wenn ein Übersetzungsschlüssel nicht gefunden wird, gibt t() den Schlüssel selbst zurück, anstatt eine Ausnahme auszulösen. Das bedeutet, Ihre App funktioniert weiterhin, auch wenn eine Übersetzung fehlt. Der Schlüssel wird unverändert angezeigt, und eine Warnung wird protokolliert, damit Sie fehlende Übersetzungen während der Entwicklung verfolgen können.

Übersetzte Komponenten implementieren

Eine übersetzte Komponente kombiniert typischerweise HasTranslation mit LocaleObserver. Verwenden Sie t(), wenn Sie UI-Elemente erstellen, um den anfänglichen übersetzten Text festzulegen. Um die Sprachanpassung zur Laufzeit zu unterstützen, implementieren Sie LocaleObserver und aktualisieren Sie denselben Text in onLocaleChange().

MainLayout.java
@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"));
}
}
Datenbindung

Das Datenbindungssystem unterstützt übersetzte Validierungs- und Transformationsnachrichten unter Verwendung von Supplier<String> mit t(). Siehe dynamische Validierungsnachrichten, dynamische Transformatornachrichten und gebietsbezogene Jakarta Validierung.

Benutzerdefinierte Übersetzungsresolver

Der Standardresolver lädt Übersetzungen aus Java ResourceBundle-Eigenschaftsdateien. Um Übersetzungen aus einer anderen Quelle, wie z.B. einer Datenbank oder einem Remote-Service, zu laden, implementieren Sie TranslationResolver:

DatabaseTranslationResolver.java
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;
}
}

Registrieren eines benutzerdefinierten Resolvers

In einer normalen webforJ-App setzen Sie den Resolver, bevor die App startet, z.B. unter Verwendung eines App-Lebenszykluslisteners:

App.setTranslationResolver(new DatabaseTranslationResolver(repository, supportedLocales));

In einer Spring Boot-App stellen Sie den Resolver als Bean zur Verfügung:

MessageSourceConfig.java
@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);
}
}
Standardresolver in Spring Boot

Wenn kein benutzerdefinierter TranslationResolver-Bean definiert ist, stellt die Spring-Auto-Konfiguration einen Standard BundleTranslationResolver bereit, der mit den unterstützten Gebietsschemata aus application.properties konfiguriert ist.