Aquí tienes un artículo completo que explica cómo implementar localización en una aplicación Blazor WebAssembly, con ejemplos de código y una explicación detallada de cada parte.
La localización permite a las aplicaciones mostrar contenido en diferentes idiomas, dependiendo de la preferencia del usuario. En una aplicación Blazor WebAssembly, implementar localización implica cargar archivos de recursos de idioma y acceder a ellos dinámicamente. En este artículo, te mostraré cómo configurar y utilizar la localización en Blazor, con ejemplos paso a paso.
1. Crear Archivos de Recursos de Idioma
El primer paso para implementar la localización es definir archivos JSON que contengan las traducciones. Estos archivos deben estar organizados por idioma. Cada archivo contiene pares clave-valor, donde la clave es un identificador único y el valor es la traducción.
Estructura de Archivos JSON
En la carpeta wwwroot/locales
, crearemos archivos para cada idioma. Por ejemplo:
es.json
(para español)en.json
(para inglés)
Archivo es.json
(español):
{
"RegisterTitle": "Registro de Usuario",
"UsernameLabel": "Nombre de Usuario",
"EmailLabel": "Correo Electrónico",
"PasswordLabel": "Contraseña",
"RegisterButton": "Registrarse",
"AlreadyHaveAccountMessage": "¿Ya tienes una cuenta?",
"LoginLinkText": "Iniciar Sesión",
"RegisterErrorMessage": "Error al registrarse, inténtalo de nuevo.",
"LoadingMessage": "Cargando..."
}
Archivo en.json
(inglés):
{
"RegisterTitle": "User Registration",
"UsernameLabel": "Username",
"EmailLabel": "Email",
"PasswordLabel": "Password",
"RegisterButton": "Register",
"AlreadyHaveAccountMessage": "Already have an account?",
"LoginLinkText": "Log In",
"RegisterErrorMessage": "Error registering, please try again.",
"LoadingMessage": "Loading..."
}
2. Crear el Servicio de Localización
Necesitamos un servicio que se encargue de cargar el archivo JSON adecuado según el idioma seleccionado por el usuario. Este servicio se encargará de gestionar las traducciones y proporcionar los textos localizados.
Código del Servicio de Localización
using System.Text.Json;
public class LocalizationService
{
private readonly HttpClient _httpClient;
private Dictionary<string, string> _translations;
public LocalizationService(HttpClient httpClient)
{
_httpClient = httpClient;
}
// Método para cargar el archivo JSON correspondiente al idioma
public async Task LoadLocalizationAsync(string lang)
{
var response = await _httpClient.GetStringAsync($"locales/{lang}.json");
_translations = JsonSerializer.Deserialize<Dictionary<string, string>>(response);
}
// Indexador que devuelve la traducción o la clave si no encuentra el valor
public string this[string key]
{
get => _translations != null && _translations.TryGetValue(key, out var value) ? value : key;
}
}
Explicación:
- El método
LoadLocalizationAsync
carga el archivo JSON de traducción desde la carpetalocales
. - Utilizamos
Dictionary<string, string>
para almacenar las claves y sus respectivas traducciones. - El indexador
this[string key]
permite acceder fácilmente a una traducción usando la clave.
3. Registrar el Servicio en Program.cs
Debemos registrar el LocalizationService
como un servicio Scoped
en Program.cs
, lo que significa que cada sesión de usuario mantendrá su propio estado de localización.
Registro del Servicio
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.Services.AddScoped<LocalizationService>();
4. Crear el Estado Global para Manejar el Idioma
Para manejar el idioma seleccionado por el usuario, podemos crear un servicio de estado global. Este servicio se encargará de almacenar el idioma actual y permitirá que todos los componentes accedan a él.
Código del Servicio de Estado Global
public class AppState
{
public string Lang { get; private set; } = "es"; // Idioma por defecto
// Método para actualizar el idioma
public void SetLang(string lang)
{
Lang = lang;
NotifyStateChanged();
}
// Evento para notificar a los componentes que el idioma ha cambiado
public event Action OnChange;
private void NotifyStateChanged() => OnChange?.Invoke();
}
Explicación:
- La propiedad
Lang
almacena el idioma actual. Por defecto está enes
(español). SetLang
actualiza el idioma y notifica a los componentes que el estado ha cambiado, lo que permite que los componentes se vuelvan a renderizar con el nuevo idioma.
Registrar el Servicio en Program.cs
También registramos el AppState
en Program.cs
:
builder.Services.AddScoped<AppState>();
5. Utilizar la Localización en los Componentes
Ahora podemos utilizar el servicio de localización en nuestros componentes para mostrar los textos traducidos.
Componente de Registro (Register.razor)
@page "/register"
@using AuthServices.Models
@inject NavigationManager Navigation
@inject LocalizationService Localizer
@inject AppState AppState
<div class="row justify-content-center w-100">
<div class="col-md-8 col-lg-6 col-xxl-3">
<div class="card mb-0">
@if (registerError)
{
<div class="alert alert-warning" role="alert">
@Localizer["RegisterErrorMessage"]
</div>
}
<div class="card-body">
<div class="text-center">
<img width="150px" src="/logo.png" alt="Logo" class="logo mb-4" />
<h3 class="mb-4">@Localizer["RegisterTitle"]</h3>
</div>
<form @onsubmit="RegisterFunction">
<div class="mb-3">
<label for="username" class="form-label">@Localizer["UsernameLabel"]</label>
<input @bind="userCredentials.Username" type="text" id="username" class="form-control" required />
</div>
<div class="mb-3">
<label for="email" class="form-label">@Localizer["EmailLabel"]</label>
<input @bind="userCredentials.Email" type="email" id="email" class="form-control" required />
</div>
<div class="mb-3">
<label for="password" class="form-label">@Localizer["PasswordLabel"]</label>
<input @bind="userCredentials.Password" type="password" id="password" class="form-control" required />
</div>
<button type="submit" class="btn btn-primary w-100">@Localizer["RegisterButton"]</button>
<div class="d-flex align-items-center justify-content-center">
<p class="fs-4 mb-0 fw-bold">@Localizer["AlreadyHaveAccountMessage"]</p>
<a class="text-primary fw-bold ms-2" href="/">@Localizer["LoginLinkText"]</a>
</div>
</form>
</div>
</div>
</div>
</div>
@code
{
private UserCredentials userCredentials = new();
private bool registerError = false;
protected override async Task OnInitializedAsync()
{
await Localizer.LoadLocalizationAsync(AppState.Lang);
}
private async void RegisterFunction()
{
// Lógica para registrar al usuario
}
}
Explicación:
- El servicio de localización
Localizer
está inyectado en el componente para acceder a los textos localizados. - Los textos como el título, etiquetas, y botones se obtienen usando claves (
RegisterTitle
,UsernameLabel
, etc.). - La llamada a
Localizer.LoadLocalizationAsync(AppState.Lang)
asegura que las traducciones correctas estén cargadas antes de mostrar el contenido.
6. Cambio de Idioma en Tiempo Real
Puedes permitir a los usuarios cambiar el idioma en cualquier momento. Para ello, basta con llamar al método SetLang
del AppState
.
Ejemplo de Cambio de Idioma:
<button @onclick="ChangeLanguageToEnglish">Change to English</button>
<button @onclick="ChangeLanguageToSpanish">Cambiar a Español</button>
@code {
private async Task ChangeLanguageToEnglish()
{
AppState.SetLang("en");
await Localizer.LoadLocalizationAsync(AppState.Lang);
}
private async Task ChangeLanguageToSpanish()
{
AppState.SetLang("es");
await Localizer.LoadLocalizationAsync(AppState.Lang);
}
}
Explicación:
- Cuando el usuario hace clic en uno de los botones, el idioma se actualiza y se recarga el archivo de traducción correspondiente.
- Todos los componentes que estén suscritos al evento
OnChange
delAppState
se volverán a renderizar automáticamente cuando el idioma cambie.
Conclusión
La localización en Blazor WebAssembly se implementa mediante la carga dinámica de archivos de traducción y el uso de un servicio que gestiona las traducciones. Con los pasos descritos en este artículo, puedes fácilmente configurar un sistema