Localización
Visión general
Crono incluye un sistema de localización basado en base de datos que cubre tanto las cadenas de la interfaz como las propiedades de las entidades. A cada solicitud se le asigna un idioma de trabajo, determinado a partir de la preferencia del usuario, la organización o la cultura de la ruta.
El idioma en curso está disponible en el contexto de trabajo:
var idioma = _trabajoContexto.IdiomaTrabajo;
Los idiomas configurados se administran con IIdiomaServicio.
Cadenas de recurso
Los textos viven en la tabla de recursos de idioma y se obtienen mediante ILocalizacionServicio o el ayudante T en controladores y vistas:
var saludo = _localizacionServicio.ObtenerRecurso("Comun.Bienvenida");
@T("Comun.Bienvenida")
ILocalizacionServicio ofrece además ObtenerTodosRecursosAsync(idiomaId), ObtenerEnumLocalizado<T>(...) para localizar los valores de un enum, y utilidades para consultar o eliminar recursos por nombre.
Anotar modelos
Aplica el atributo LocalizadoMostrar a las propiedades del modelo para que sus etiquetas se tomen de la tabla de recursos. Por convención, la clave del recurso coincide con el nombre de la propiedad. Decorando la clase con un prefijo, las propiedades pueden usar claves más cortas (con *):
[LocalizadoMostrar("Admin.Dominio.Campos.")]
public class ConfiguracionModelo : ModeloBase
{
[LocalizadoMostrar("*MiAjuste")]
public bool MiAjuste { get; set; }
}
Para mostrar un tooltip junto a la etiqueta, crea un segundo recurso con el sufijo .Hint.
Localizar entidades
Los tipos de entidad que admiten traducciones implementan IEntidadLocalizada; opcionalmente se decoran con EntidadLocalizadaAttribute para indicar su grupo de clave. Los valores por idioma se guardan en la tabla PropiedadLocalizada, identificados por grupo de clave, entidad e idioma.
Usa IEntidadLocalizadaServicio para leer y aplicar valores por idioma:
// Leer el valor localizado de una propiedad
var nombre = await _entidadLocalizadaServicio.ObtenerValorLocalizadoAsync(
idioma.Id, producto.Id, claveGrupoLocal: "Producto", claveLocal: "Nombre");
// Aplicar (guardar) un valor localizado
await _entidadLocalizadaServicio.AplicarValorLocalizadoAsync(
producto, p => p.Nombre, "Nombre traducido", idioma.Id);
Para conjuntos grandes, PrecargarPropiedadesLocalizadasAsync y ObtenerColeccionPropiedadesLocalizadasAsync cargan las propiedades localizadas por lotes, evitando consultas repetidas. La sincronización de traducciones al guardar la refuerza el EntidadLocalizadaInterceptor (ver Interceptores).
Agregar recursos mediante migraciones
Cuando el núcleo o un módulo introduce nuevos textos, se agregan a través de una migración de FluentMigrator que implementa el proveedor de recursos de idioma y siembra las claves durante la migración (ver Migraciones de base de datos). Los recursos se combinan en la tabla de recursos para todos los idiomas.