Localización
Plugster trae un helper de localización pequeño, intencionalmente minimalista. No es una librería completa de i18n — no hay cadena de fallback de locales, no hay formas plurales, no hay paquetes de mensajes cargados desde disco. Lo que ofrece alcanza para los casos que al framework le importan: un Plugster que tiene texto orientado al usuario necesita una forma de renderizar ese texto en el idioma activo, escogido en el momento del render de la vista por el servidor. La API son dos métodos en cada instancia de Plugster: setLocales y translateTo.
setLocales
#
setLocales registra las tablas de traducción por idioma para esta instancia de Plugster. El argumento es un objeto cuyas claves son códigos de idioma (los mismos códigos que pones en data-lang) y cuyos valores son diccionarios que mapean el texto completo en inglés a su versión traducida.
export class SignInPlugster extends Plugster {
constructor(outlets, createOneTimePin) {
super(outlets);
this._createOneTimePin = createOneTimePin;
this.setLocales({
'es': {
'Sign in': 'Iniciar sesión',
'Email': 'Correo electrónico',
'Sending the one-time pin...': 'Enviando el código de un solo uso...'
}
});
}
}
Nota que la convención es el texto completo en inglés como clave, no un código corto como 'sign-in.title'. La razón es que el render por defecto — el caso donde no se encuentra traducción — cae al valor de la clave misma. Con inglés completo como clave, el peor caso es que la página se renderiza en inglés; con códigos cortos, el peor caso es que la página renderiza identificadores visibles como sign-in.title al usuario.
setLocales pertenece al constructor. No toca el DOM y es seguro llamarlo antes de que corra init().
translateTo
#
translateTo(language, text) busca la traducción del texto inglés dado en el idioma dado, y devuelve el texto original sin cambios si no hay entrada. Está pensado para llamarse desde afterInit() y desde cualquier handler que necesite renderizar texto después de eso.
afterInit() {
let self = this;
self.lang = self._.root.data('lang');
self._.titleLabel.text(self.translateTo(self.lang, 'Sign in'));
self._.emailInput.attr('placeholder', self.translateTo(self.lang, 'Email'));
self._.submitButton.on('click', function () {
self._.statusLabel.text(self.translateTo(self.lang, 'Sending the one-time pin...'));
self._createOneTimePin(self._.emailInput.val());
});
}
Tres comportamientos de translateTo que vale conocer:
-
Tabla de idioma faltante → devuelve la entrada. Si
setLocalesnunca se llamó para el idioma pedido, el método devuelve el texto inglés sin cambios. La página renderiza correctamente, solo que en inglés. - Clave faltante en una tabla existente → devuelve la entrada. Si la tabla de idioma existe pero no contiene la clave pedida, el método devuelve el texto inglés sin cambios. Mismo resultado: fallback al inglés.
-
Idioma vacío o indefinido → devuelve la entrada. Si
self.langes vacío (el atributodata-langno se configuró), la búsqueda corta el circuito y devuelve la entrada. No hace falta proteger el call site con unif.
Obtener el idioma activo #
El framework no escoge el idioma activo por ti. La convención es que la plantilla del servidor que renderiza la vista escribe el código de idioma en el elemento de la vista vía data-lang, y el controlador lo lee desde el outlet implícito root durante afterInit():
<div data-controller-name="SignInPlugster"
data-lang="{{ lang_code }}">
...
</div>
afterInit() {
this.lang = this._.root.data('lang');
// ... usa this.lang con translateTo(...)
}
Guardar el valor en la instancia (this.lang) mantiene cada call site corto. También significa que cambios subsiguientes en tiempo de ejecución al atributo data-lang no afectan el texto ya renderizado — la localización de Plugster es un disparo por render, no un binding reactivo.
Dónde pertenece la localización #
Para texto estático de la página que la plantilla del servidor controla (títulos, encabezados, cuerpo que vive en el HTML directamente), usa la maquinaria de localización del servidor — el helper {{ _() }} en vistas Plugster renderizadas por Jinja, por ejemplo. El servidor ya sabe el idioma activo y puede renderizar el texto correcto en el HTML antes de que el Plugster lo vea siquiera.
setLocales / translateTo son para texto que el Plugster mismo produce en tiempo de ejecución: etiquetas de estado actualizadas después de una llamada de red, etiquetas de botón intercambiadas durante un flujo, ítems agregados a un outlet de lista (cuya plantilla de fila es HTML estático y por lo tanto inalcanzable por el localizador del servidor). Cualquier cosa que el controlador escriba en el DOM después de init() es candidato.
Todo junto #
<div data-controller-name="SignInPlugster"
data-lang="{{ lang_code }}">
<h2 data-outlet-id="titleLabel"></h2>
<input data-outlet-id="emailInput" type="email">
<button data-outlet-id="submitButton"></button>
<p data-outlet-id="statusLabel"></p>
</div>
import {Plugster} from "https://cdn.jsdelivr.net/gh/paranoid-software/plugster@1.0.14/dist/plugster.min.js";
export class SignInPlugster extends Plugster {
constructor(outlets) {
super(outlets);
this.setLocales({
'es': {
'Sign in': 'Iniciar sesión',
'Email': 'Correo electrónico'
}
});
}
afterInit() {
let self = this;
self.lang = self._.root.data('lang');
self._.titleLabel.text(self.translateTo(self.lang, 'Sign in'));
self._.submitButton.text(self.translateTo(self.lang, 'Sign in'));
self._.emailInput.attr('placeholder', self.translateTo(self.lang, 'Email'));
}
}
Renderiza la página con lang_code = 'en' y obtienes el texto inglés vía el camino de fallback. Renderízala con lang_code = 'es' y los mismos caminos de código producen salida en español. No se necesita cableado adicional.