Internacionalización¶
Adaptive Learner se entrega en 8 idiomas, todos completamente
traducidos desde v1.13.0 / Fase 26: DE, EN, ES, FR, EL, PT, TR,
JA. Según la regla del proyecto, el contenido en alemán usa
umlauts reales (ä, ö, ü, ß) — el alemán con ASCII está prohibido
en de.yaml y docs/help/de/**. test_i18n_translation_audit.py
fija tanto la cobertura de umlauts como el umbral de ≥90% de
divergencia respecto a EN para los catálogos que anteriormente
eran pasaporte inglés.
Dónde viven las cadenas¶
Backend¶
Catálogos YAML en backend/config/i18n/{lang}.yaml — un archivo
por idioma. El catálogo de referencia es EN; cada otro catálogo
debe tener el mismo árbol de claves.
# backend/config/i18n/en.yaml
common:
save: Save
cancel: Cancel
settings:
title: Settings
section_language: Language
...
El backend expone GET /api/i18n/{lang} que devuelve el catálogo
completo como JSON. El hook useI18n del frontend lo llama en el
primer renderizado y almacena el resultado en caché.
Fallbacks del frontend¶
frontend/src/i18n/fallbacks.ts contiene un subconjunto en línea
de cadenas codificadas en el bundle del frontend. Estas se muestran
en el primer renderizado antes de que se haya cargado el catálogo
del backend — y como fallback permanente si el endpoint del
catálogo devuelve 5xx.
La cadena de resolución de fallback en useI18n:
- Catálogo del backend (cadenas en vivo desde
/api/i18n/{lang}). Recorre la ruta de notación por puntos. - Fallbacks del frontend codificados (resiliencia en el primer renderizado).
- Cadena de fallback proporcionada por el llamador.
- La clave misma.
Ayuda en la aplicación / sitio de documentación¶
docs/help/_meta.yaml declara el árbol de navegación con títulos
en DE + EN por entrada. El panel de ayuda en la aplicación lo lee
directamente; scripts/generate_mkdocs_nav.py regenera el bloque
de navegación de mkdocs.yml desde la misma fuente.
El Markdown de las páginas de ayuda vive en docs/help/{lang}/...
— una carpeta por idioma. El modo docs_structure: folder de
mkdocs-static-i18n gestiona la resolución.
Añadir un nuevo idioma¶
- Catálogo del backend: copia
backend/config/i18n/en.yamlabackend/config/i18n/{nuevoidioma}.yaml. Traduce cada valor de forma nativa (sin pasaporte EN — la prueba de auditoría de traducción fallará con <90% de divergencia). Luego ejecutamake sync-i18npara reflejar el catálogo enfrontend/src/data/i18n/{nuevoidioma}.json(el bundle del modo Dexie que el hotfix v1.16.0 hizo resiliente en el primer renderizado). - Constantes del frontend: añade el código del idioma a
SUPPORTED_LANGUAGESenfrontend/src/lib/constants.ts. - Fallbacks del frontend: añade un bloque
{nuevoidioma}: {...}afrontend/src/i18n/fallbacks.tscon el pequeño subconjunto de cadenas que usa la ruta de código del primer renderizado. - Preguntas de la evaluación: edita
plugins/adaptive-learner-plugin-assessment/adaptive_learner_assessment/questions.py— añade un campotext_{nuevoidioma}a cada entrada deQUESTIONSy a cada respuesta. Vuelve a exportar el JSON:poetry run python plugins/.../questions.py --export-json frontend/src/data/assessment-questions.json(este CLI no existe aún; el script enscripts/necesitaría una pequeña adición). - Prompts de sesión: edita
plugins/adaptive-learner-plugin-session/adaptive_learner_session/prompts.pypara añadir una tercera clave de idioma a cada celda (método, paso). Vuelve a exportar el JSON de la misma manera. - Sitio de documentación: actualiza el bloque
plugins.i18n.languagesdemkdocs.ymly añade el directoriodocs/help/{nuevoidioma}/reflejando la estructura EN.
Pruebas de paridad¶
backend/tests/test_i18n_parity.py recorre cada catálogo y
verifica que:
- Cada idioma tiene cada clave que tiene la referencia (EN).
- Ningún idioma tiene una clave extra que la referencia no tenga.
Esto detecta el bug de deriva más común: alguien añade una clave
en EN y se olvida de añadirla en los otros 7 archivos. Ejecuta
make test-backend después de cualquier cambio en el catálogo.
Plurales¶
Los catálogos actuales no usan la sintaxis de plural ICU. Los pocos recuentos que renderizamos (número de sesiones, días de racha) tienen la selección de forma codificada en TS:
Las cadenas de plural ICU mediante mkdocs-i18n o una biblioteca ICU en tiempo de ejecución están en la lista de trabajo aplazado.
Idiomas RTL¶
El árabe, el hebreo, el persa, etc. necesitarían soporte de maquetación bidireccional en el CSS. El tema actual asume LTR; añadir RTL está en la lista de trabajo aplazado.
Cuándo NO añadir una cadena¶
Si una cadena solo aparece en superficies destinadas a
desarrolladores (mensajes de error lanzados por
AdaptiveLearnerError, líneas de registro, datos de
fixtures de pruebas), déjala en inglés. La maquinaria de
internacionalización es solo para cadenas visibles por el usuario
final.
Las llamadas console.warn y console.error del frontend también
se mantienen en inglés — son para desarrolladores que leen la
consola del navegador, no para usuarios finales.