El proceso de localización de un proyecto de código abierto 

Translation into Spanish of an interesting article by Dima Enns, a Russian software developer located in Germany. Dima shares with us his strategy to localize apps easily through a clever use of localization files categorization, and the help of 2 small apps he has developped to manage and combine these files. Good job!

código abiertolocalizationspanish translation
30 March, 2022 Localización, contratiempos que he solucionado.
30 March, 2022 Localización, contratiempos que he solucionado.

A free translation by Chema, a Spain-based translator specializing in translating software and apps from English into Spanish.

An original text written by Dima Enns, originally published in
https://dev.to/yeah69/the-road-to-localization-in-an-open-source-project-1o09

* * *

Optar por traducir y localizar mi proyecto de código abierto (OS) me ha obligado a aprender mucho y superar algunos problemas. En esta entrada del blog me gustaría describir exactamente esto.

Los obstáculos de la localización

Hay muchas cuestiones que dificultan la localización de un programa de software:

  • O lo haces todo o no lo haces. Nadie quiere trabajar con un producto parcialmente traducido / localizado.
  • Se necesita esfuerzo y trabajo constantes. Cada nuevo desarrollo, cada nueva función, implica nuevos textos que deben ser traducidos / localizados.
  • Es necesario conocer bien el idioma que se va a traducir / localizar y los idiomas son muy difíciles de aprender (como probablemente casi todo el mundo sepa por experiencia propia).
  • Todo esto retrasa y complica el proceso. ¿Es mejor hacer las localizaciones en paralelo al desarrollo? ¿Y si los textos cambian después? ¿Pueden trabajar los traductores sin ver los textos en el contexto de la aplicación? ¿O es mejor hacer las traducciones de forma secuencial después de desarrollar cada función? Esto retrasaría mucho el lanzamiento….
  • Traducir o no una aplicación de software es una cuestión de desarrollo que marca una gran diferencia. En el caso de las localizaciones, es necesaria una capa de abstracción, porque los textos localizados deben ser intercambiables en diversas ubicaciones. La comodidad de no ofrecer traducción ninguna es tentadora, claro, porque ahorra mucho esfuerzo y complejidad en el desarrollo de software.

Este es un gran reto incluso para empresas de software. En mi caso solo soy yo, frente a mi proyecto como desarrollador recreativo de código abierto, planteándome si debo traducirlo y localizarlo, o no. Para los proyectos de código abierto (especialmente los pequeños como el mío) el obstáculo es aún mayor, debido a la falta de recursos. Es una lástima, porque muchas aplicaciones de código abierto podrían ser relevantes para aquellos que, al mismo tiempo, no pueden permitirse alternativas comerciales y no saben inglés ni otros idiomas comúnmente localizados. Es decir, donde el beneficio parece grande, el obstáculo es aún mayor. Para contarlo me gustaría hacer un pequeño recorrido por la historia de mis experiencias en la localización de mi proyecto de SO.

Un poco de historia sobre mis experiencias personales con la localización de un proyecto de SO

En primer lugar, un pequeño disclaimer. Nací en Rusia y vine a Alemania cuando tenía seis años. Eso significa que hablo 3 idiomas: Alemán, Inglés y algo de Ruso (clasificados por nivel).

Y ahí me tienes, empezando mi proyecto OS, destinado a la contabilidad privada (todavía “bastante poco maduro” para su lanzamiento, por desgracia). Se supone que debe ayudar a la gente a tener sus finanzas bajo control. La gente que no tiene problemas de dinero no necesita depender de él. Por esto tiene que ser gratuito. También debe poder llegar al mayor número de personas posible. Así que también debe servir a los que no saben hablar inglés. Por tanto, la pregunta “Localizaciones sí o no?” se responde así con un claro “¡Por supuesto que sí!”

Al principio decidí traducir y localizar sólo en Inglés y Alemán, porque estos idiomas eran lo suficientemente buenos para mis necesidades. El Ruso no me atreví a hacerlo, porque nunca fui a la escuela en Rusia y, por tanto, estaba muy lejos de dominar la terminología. Esto demuestra por sí solo que, cuando trabajas en un proyecto tú solo, solo puedes ocuparte de la localización hasta donde llegan tus habilidades. Y las mías, por desgracia, son muy limitadas. Demasiado limitadas. Sin embargo, esto me obligó a estructurar bien el código para su mejor localización / traducción, por lo que para otros idiomas “sólo” hay que traducir los textos existentes.

Para más idiomas necesitaba ayuda y la busqué. La encontré en mi tía. Ella también nació en Rusia y trabaja en el campo de las finanzas. Perfecto. Además, en ese momento tenía una novia húngara, que por suerte aceptó ayudarme (Szia, magyarország. Hogy vagy?). Tenía su OK, pero aún así dudaba si debía aprovechar su ayuda. El programa debía estar en un estado de desarrollo óptimo. Tenía muy claro que no quería dejar que estos ayudantes de traductores, muy queridos para mí, trabajaran innecesaria y regularmente de forma totalmente gratuita. Tenía un mal presentimiento al respecto.

Al final decidí aprovechar la oportunidad y traducir mi proyecto a cuatro idiomas (de un total de 7.111 idiomas, según la wikipedia). Sí. Y luego, consciente o inconscientemente, procrastiné con funciones que necesitaban nuevos textos. Preferí ocuparme de otras cosas que no requerían nuevos textos, lo cual no es malo per se, pero inhibe el desarrollo del verdadero propósito del proyecto. Cuando empecé de nuevo con las nuevas funciones, puse los valores en Inglés en las localizaciones en Ruso y Húngaro como placeholders para los nuevos textos. Esto es lo que ocurrió con el proyecto hasta hace unas semanas, cuando desarrollé una nueva solución para mí. No me apetecía preguntar a mi tía. Y la relación con mi novia húngara de entonces había terminado.

La solución que se me ocurrió

He resuelto (la mayoría) de los problemas que tenía con las localizaciones con la ayuda de 2 proyectos. Son 2 desarrollos muy especializados diseñados para C#/WPF/DeepL. Si trabajas C#/WPF/DeepL, pruébalos! Estoy deseando recibir comentarios. Los detalles técnicos se encuentran en las wikis de los respectivos proyectos (MrMeeseeks.ResXTranslationCombinator / MrMeeseeks.ResXToViewModelGenerator). Puedes echar un vistazo si estás interesado. Los conceptos pueden ser fácilmente reutilizables para su aplicación a otros proyectos similares.

Desgraciadamente, no puedo saltarme una breve y escueta definición de la terminología, así que, cuanto antes mejor!

En mis proyectos distingo 4 categorías de archivos de localización:

  • El archivo por defecto, que especifica las claves de localización y los textos que serán localizados.
  • Los archivos automáticos, con las mismas claves que el archivo estándar, pero con textos traducidos: uno para cada idioma.
  • Los archivos override (de anulación), con las mismas claves que el archivo por defecto, pero con textos traducidos: uno por cada idioma como máximo. Ofrecen la posibilidad de anular y sustituir de forma manual y selectiva las traducciones automáticas.
  • Los archivos combinados, con las mismas claves que el archivo estándar, pero con los textos traducidos: uno por cada idioma. Los textos se combinan a partir de un archivo automático y, caso de existir, de un archivo de anulación.

Ahora una descripción aproximada de los dos proyectos y lo que hacen:

  • MrMeeseeks.ResXTranslationCombinator – como el nombre y la definición de la terminología sugieren: este proyecto obtiene el archivo por defecto y los archivos de anulación, y genera los archivos automáticos y combinados. A partir de ahora lo llamaré simplemente TranslationCombinator.
  • MrMeeseeks.ResXToViewModelGenerator – este proyecto obtiene el archivo por defecto y los archivos combinados. A partir de ahí genera ViewModels de localización que pueden ser convenientemente utilizados de acuerdo con el Patrón Modelo-Vista-Vista-Modelo (MVVM). A partir de ahora lo llamaré simplemente ViewModelGenerator.

Estar´ía encantado de seguir esta tortura con más detalles de concepto y experiencias personales sobre estos proyectos, per intentaré contenerme…

El Combinador de Traducciones

El TranslationCombinator se implementa como un paso de una acción de Github. Si sigues el flujo de trabajo -documentado y recomendado en el repositorio-, el paso reacciona tan pronto como se realizan cambios en los archivos de localización. A continuación, utiliza el servicio de traducción (yo elegí DeepL; ten en cuenta que necesitas una cuenta para acceder a la API de DeepL) para crear o complementar los archivos automáticos. Después, teniendo en cuenta los archivos que se anulan, se crean o complementan los archivos combinados. Por último, pero no por ello menos importante, se crea un pull request si el proceso dio lugar a cambios en los archivos.

Lo ideal es que los desarrolladores sólo tengan que hacer cambios en el archivo por defecto en cuanto necesiten nuevas localizaciones. Lo ideal es que los traductores no tengan que intervenir. Sin embargo, pueden proporcionar anulaciones (override) a las localizaciones cuando surja la necesidad. Todo lo demás lo hace el TranslationCombinator. Esto también permite una colaboración completamente asíncrona entre los desarrolladores y los traductores.

Opciones interesantes:

  • El servicio de traducción detecta automáticamente el idioma de origen, por lo que puedes elegir cualquiera de los idiomas admitidos en el archivo por defecto sin especificar explícitamente cuál es.
  • Los archivos automáticos actúan como cachés. Sólo se crean traducciones para los valores que faltan. Si los mantenedores quieren que un valor se traduzca de nuevo automáticamente, pueden simplemente eliminar el valor.
  • TranslationCombinator crea un archivo plantilla para anular archivos. Si deseas anular los textos de un determinado idioma, basta con renombrar el archivo de plantilla en lugar de copiarlo y pegarlo. En el próximo pull request se creará el archivo plantilla en este caso.
  • Puedes anular manualmente un idioma no soportado si rellenas completamente un archivo de anulación. Sin embargo, en este caso debes asegurarte de suministrar las traducciones manuales para las nuevas claves, de lo contrario estas localizaciones quedarán vacías.
  • Una lección que tuve que aprender: ¡El TranslationCombinator debe ordenar las claves de los archivos generados! De lo contrario, el pull request diff explotará.

El ViewModelGenerator

Los archivos de localización tienen un formato XML que no está diseñado para su uso directo en proyectos MVVM. Aquí es donde el ViewModelGenerator ayuda. Toma el archivo por defecto y los archivos combinados y genera un conjunto de interfaces y clases ViewModel a partir de ellos. Éstas pueden ser leídas directamente desde los elementos de las capas View y ViewModel. También proporcionan una forma cómoda y eficaz de cambiar de idioma en tiempo de ejecución.

El proyecto de muestra

He creado un tercer repositorio. Éste es sólo un proyecto de ejemplo que utiliza los otros dos proyectos en combinación. Si quieres ver un ejemplo completo en acción, no dudes en echarle un vistazo. Ten en cuenta que me he centrado en el proceso de localización. Esto significa que el resto del código no está a la altura de mis estándares habituales. Aquí hay una pequeña animación del resultado (paso por todos los idiomas una vez “lentamente” y luego unas cuantas veces a toda velocidad):

Language Switching

También puedes echar un vistazo al nuevo flujo de trabajo de localización en el ya mencionado proyecto de afición a la contabilidad (Proyecto BFF).

Reflexiones finales

¿Se han resuelto ya todos los problemas de localización? No, desde luego que no. Pero estamos dos pasos más cerca del objetivo de minimizar el esfuerzo humano. Ahora no tengo que cargar a mi tía y a mi ex novia con más trabajo. Sí. Lo mejor es que automáticamente se genera una localización base y los traductores son siempre bienvenidos a contribuir si lo desean. No se presiona a nadie para que se encargue de las localizaciones, pero quien quiera tiene la oportunidad de participar activamente. En mi opinión, esto vale su peso en oro para un proyecto de código abierto.

Valora este artículo