Saltar al contenido principal

Traducción 25.12

Abrir en ChatGPT

webforJ incluye un sistema de traducción integrado para buscar cadenas localizadas por clave. El sistema consta de un resolutor de traducción que asigna claves a texto localizado, una interfaz de preocupación HasTranslation que proporciona un conveniente método t(), App.getTranslation() para acceso directo en cualquier lugar, detección automática de la configuración regional desde el navegador y soporte para fuentes de traducción personalizadas como bases de datos.

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

Resolutor de traducción

El resolutor de traducción es el sistema que busca cadenas localizadas para una clave y configuración regional dada. webforJ proporciona un resolutor predeterminado, BundleTranslationResolver, que carga traducciones de archivos de propiedades ResourceBundle de Java en el classpath. Esto funciona directamente sin dependencias adicionales.

Archivos de paquetes de recursos

Coloca tus archivos de traducción en el directorio src/main/resources. El resolutor predeterminado busca archivos llamados messages con sufijos de configuración regional siguiendo la convención de nomenclatura estándar de ResourceBundle de Java:

messages.properties # Traducciones predeterminadas/por defecto
messages_en.properties # Inglés
messages_de.properties # Alemán
messages_fr_CA.properties # Francés (Canadá)

Cada archivo contiene pares de clave-valor. Las claves son identificadores que usas en el código y los valores son las cadenas traducidas. Puedes incluir marcadores de posición de MessageFormat como {0}, {1} para valores dinámicos:

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

El resolutor delega en la cadena de resolución estándar de ResourceBundle de Java, que maneja la coincidencia de configuración regional y la caída automáticamente.

Configurando configuraciones regionales soportadas

La configuración supported-locales le indica a webforJ qué configuraciones regionales soporta tu aplicación. Esta lista es utilizada por la detección automática para comparar la configuración regional del navegador del usuario con las traducciones disponibles. La primera configuración regional de la lista se utiliza como el fallback predeterminado cuando no se encuentra una coincidencia mejor. La clave de propiedad es webforj.i18n.supported-locales y acepta una lista de etiquetas de idiomas BCP 47, por ejemplo en, de.

Más información

Consulta la sección Configuración para aprender cómo establecer propiedades para diferentes entornos.

El método t()

Los componentes que implementan la interfaz de preocupación HasTranslation obtienen acceso al método t() para traducir texto. El método toma una clave de traducción y devuelve la cadena localizada para la configuración regional actual de la aplicación:

public class MainLayout extends Composite<AppLayout> implements HasTranslation {

public MainLayout() {
// Traducción simple
String title = t("app.title");

// Traducción con parámetros de MessageFormat
String greeting = t("greeting", userName, messageCount);

// Traducción para una configuración regional específica
String germanTitle = t(Locale.GERMAN, "app.title");
}
}

También puedes usar App.getTranslation() directamente en cualquier lugar sin implementar la interfaz:

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

Si no se encuentra una clave de traducción, t() devuelve la clave en sí en lugar de lanzar una excepción. Esto significa que tu aplicación no se romperá si falta una traducción. La clave se muestra tal cual, y se registra una advertencia para que puedas rastrear traducciones faltantes durante el desarrollo.

Implementando componentes traducidos

Un componente traducido combina típicamente HasTranslation con LocaleObserver. Utiliza t() al crear elementos de la interfaz de usuario para establecer el texto traducido inicial. Para soportar el cambio de idioma en tiempo de ejecución, implementa LocaleObserver y actualiza el mismo texto en 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"));
}
}
Vinculación de datos

El sistema de vinculación de datos soporta mensajes de validación y transformación traducidos utilizando Supplier<String> con t(). Consulta mensajes de validación dinámicos, mensajes de transformador dinámicos, y validación consciente de la configuración regional de Jakarta.

Resolutores de traducción personalizados

El resolutor predeterminado carga traducciones de archivos de propiedades ResourceBundle de Java. Para cargar traducciones de una fuente diferente, como una base de datos o un servicio remoto, implementa 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;
}
}

Registrando un resolutor personalizado

En una aplicación webforJ normal, establece el resolutor antes de que la aplicación se inicie, por ejemplo, usando un escuchador del ciclo de vida de la aplicación:

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

En una aplicación de Spring Boot, expón el resolutor como un 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);
}
}
Resolutor predeterminado en Spring Boot

Cuando no se define un bean TranslationResolver personalizado, la auto-configuración de Spring proporciona un BundleTranslationResolver predeterminado configurado con las configuraciones regionales soportadas de application.properties.