i18n

Cómo funciona la traducción de la interfaz en todos los clientes

Tabla de contenidos

Descripción general

Cada texto de la interfaz de Pankosmia se busca mediante una clave en un árbol de traducción compartido, de modo que todos los clientes (panel, ajustes, gestores de contenido…) siguen el mismo idioma. Una clave tiene tres partes unidas por dos puntos: <categoría>:<sección>:<nombre>, por ejemplo pages:core-settings:title. El valor de una clave contiene una traducción por código de idioma (en, fr, es, id…). Cuando no se encuentra una clave, se muestra la propia clave.

Estructura del árbol de traducción

Categoría Contenido
pages Una sección por cliente, con el nombre del id del cliente, rellenada desde el objeto i18n de su pankosmia_metadata.json. Ejemplo: pages:core-settings:title.
library Textos de bibliotecas compartidas como la RCL. Ejemplo: library:pankosmia-rcl:required_field.
components Textos de partes compartidas de la interfaz (cabecera, mensajes del framework…). Ejemplo: components:framework:no_entry_if_offline.
branding Identidad del producto. Ejemplo: branding:software:name.
scripture Nombres de libros y de versificaciones.
munchers, crunchers, flavors, server, fonts Otras categorías de la plantilla, usadas por ciertos gestores de contenido y funciones del servidor.

De dónde vienen los textos

  • La plantilla: el archivo base i18n.json de resource-core/templates. La compilación de la aplicación de escritorio lo copia a lib/templates/i18n.json. Contiene library, components, branding, scripture…
  • Cada cliente: el objeto i18n de su pankosmia_metadata.json. Una clave title del cliente core-settings se convierte en pages:core-settings:title.
  • El producto: i18nPatch.json y i18n-overrides.json en los globalBuildResources de la aplicación de escritorio (véase más abajo).

Cómo carga un cliente las traducciones

Cuando arranca un cliente, el componente SpSpa de la RCL solicita /api/i18n/flat al servidor y guarda el resultado en el contexto i18n. La respuesta es un mapa plano de clave a texto, para el idioma elegido por el usuario en el cliente Ajustes (guardado mediante /api/settings/languages). Los componentes lo leen con i18nRef.current y buscan una clave con doI18n.

Usar las traducciones en el código

Ambas funciones vienen de pankosmia-lib/i18n. doI18n(clave, source) devuelve el texto, o la propia clave si falta. doInterpolatedI18n(clave, valores, source) rellena los marcadores %1%, %2%… de un texto con una matriz de cadenas.

import { useContext } from "react";
import { i18nContext } from "pankosmia-rcl";
import { doI18n, doInterpolatedI18n } from "pankosmia-lib/i18n";

const { i18nRef } = useContext(i18nContext);

doI18n("pages:core-settings:title", i18nRef.current);

// "greeting": { "en": "Hello %1%, you have %2% books" }
doInterpolatedI18n(
  "pages:my-client:greeting",
  ["Ada", "3"],
  i18nRef.current,
);

doInterpolatedI18n es más estricta que doI18n: lanza un error si falta la clave, si un valor no es una cadena, si el número de valores difiere del de marcadores, o si un marcador está mal formado.

Añadir un texto a un cliente

  1. Añada la clave al objeto i18n del pankosmia_metadata.json del cliente, con al menos la traducción en.
  2. Úsela en el código como pages:<id del cliente>:<clave>.
  3. Recompile el cliente. Se pueden añadir otros idiomas en el archivo o con el editor de localización.
{
  "id": "my-client",
  "i18n": {
    "title": { "en": "My client", "fr": "Mon client" }
  }
}

Editor de localización

El cliente core-client-i18n-editor (id i18n-editor) edita todo el árbol de traducción. Lo lee desde /api/i18n/raw y lo guarda con un POST a /api/i18n. Solo permite editar los textos y añadir o quitar códigos de idioma. Requiere el modo de depuración (require.debug es true), por lo que aparece en la sección Depuración del menú.

Personalización a nivel de producto

Una aplicación de escritorio puede ajustar textos sin tocar los clientes, con dos archivos de sus globalBuildResources:

  • i18nPatch.json: se aplica en la compilación mediante buildCommon.js sobre templates/i18n.json. Cada entrada debe existir ya en la plantilla, de lo contrario la compilación falla. En la práctica solo contiene el nombre del producto (branding.software.name.en), que el script app_setup mantiene igual a APP_NAME.
  • i18n-overrides.json: se copia a app_resources/product/i18n-overrides.json. Tiene el mismo propósito, con la forma { "pages": { } } (vacío por defecto).