Zum Hauptinhalt springen

Übersetzung 25.12

In ChatGPT öffnen

webforJ enthält ein integriertes Übersetzungssystem zum Abrufen lokalisierter Zeichenfolgen über Schlüssel. Das System besteht aus einem Übersetzungsresolver, der Schlüssel auf lokalisierte Texte abbildet, einem HasTranslation Concern-Interface, das eine bequeme t()-Methode bereitstellt, App.getTranslation() für den direkten Zugriff überall, automatischer Erkennung der Regionaleinstellung aus dem Browser und Unterstützung für benutzerdefinierte Übersetzungsquellen wie Datenbanken.

AI skill available

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."

Übersetzungsresolver

Der Übersetzungsresolver ist das System, das lokalisierte Zeichenfolgen für einen gegebenen Schlüssel und eine Regionaleinstellung nachschlägt. webforJ bietet einen Standardresolver, BundleTranslationResolver, der Übersetzungen aus Java ResourceBundle-Eigenschaftsdateien im Klassenpfad lädt. Dies funktioniert sofort ohne zusätzliche Abhängigkeiten.

Ressourcenbündeldateien

Platzieren Sie Ihre Übersetzungsdateien im Verzeichnis src/main/resources. Der Standardresolver sucht nach Dateien mit dem Namen messages, die den Standardbenennungsrichtlinien für Java ResourceBundle folgen:

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 Zeichenfolgen. 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 standardmäßige ResourceBundle Auflösungskette von Java, die die Sprachübereinstimmung und den Fallback automatisch behandelt.

Unterstützte Regionen einstellen

Die Einstellung supported-locales sagt webforJ, welche Regionen Ihre App unterstützt. Diese Liste wird von der automatischen Erkennung verwendet, um die Regionaleinstellung des Browsers des Benutzers mit den verfügbaren Übersetzungen abzugleichen. Die erste Region in der Liste wird als Standardfallback verwendet, wenn keine bessere Übereinstimmung gefunden wird. Der Eigenschaftsschlüssel ist webforj.i18n.supported-locales und akzeptiert eine Liste von BCP 47 Sprach-Tags, zum Beispiel en, de.

Mehr Informationen

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

Die t()-Methode

Komponenten, die das HasTranslation Concern-Interface implementieren, erhalten Zugriff auf die t()-Methode zur Übersetzung von Texten. Die Methode nimmt einen Übersetzungsschlüssel und gibt die lokalisierte Zeichenfolge für die aktuelle App-Regionaleinstellung 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 eine bestimmte Region
String germanTitle = t(Locale.GERMAN, "app.title");
}
}

Sie können auch App.getTranslation() direkt überall verwenden, ohne das Interface 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, dass Ihre App nicht abstürzt, wenn eine Übersetzung fehlt. Der Schlüssel wird so angezeigt, wie er ist, und eine Warnung wird protokolliert, damit Sie fehlende Übersetzungen während der Entwicklung verfolgen können.

Implementierung übersetzter Komponenten

Ein übersetzter Bestandteil kombiniert typischerweise HasTranslation mit LocaleObserver. Verwenden Sie t(), wenn Sie UI-Elemente erstellen, um den initialen übersetzten Text festzulegen. Um die Sprachen zur Laufzeit zu wechseln, implementieren Sie LocaleObserver und aktualisieren 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 mit Supplier<String> zusammen mit t(). Siehe dynamische Validierungsnachrichten, dynamische Transformatornachrichten und locale-bewusste Jakarta-Validierung.

Benutzerdefinierte Übersetzungsresolver

Der Standardresolver lädt Übersetzungen aus Java ResourceBundle-Eigenschaftsdateien. Um Übersetzungen aus einer anderen Quelle zu laden, wie z. B. einer Datenbank oder einem Remote-Dienst, 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;
}
}

Registrierung eines benutzerdefinierten Resolvers

In einer einfachen webforJ-App setzen Sie den Resolver vor dem Start der App, beispielsweise mit einem App-Lebenszyklus-Listener:

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

In einer Spring Boot-App exponieren Sie den Resolver als Bean:

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 keine benutzerdefinierte TranslationResolver-Bean definiert ist, stellt die Spring-Auto-Konfiguration einen Standard-BundleTranslationResolver bereit, der mit den unterstützten Regionen aus application.properties konfiguriert ist.