Localización de Ruby: i18n, g18n, gettext, padrino... ¿cuál es la diferencia?




localization internationalization (3)

Al ser algo nuevo en Ruby, estoy explorando bibliotecas existentes para hacer lo que normalmente haría en otros lenguajes de scripting, y estoy un poco perplejo por las bibliotecas de localización que podrían estar disponibles para algo creado sobre Sinatra / Sequel (Rails / AR siendo un poco demasiado a mi gusto).

Ahora, me encontré con una pareja (i18n, r18n, GetText) a través de esta página wiki , y aparentemente hay una biblioteca adicional utilizada en Padrino (basada en la cosa i18n de Rails?); y al parecer mucho más.

Excepto por lo obvio (es decir, archivos GetText mo / po style vs yml), estoy algo confundido en cuanto a cómo estas opciones podrían ser diferentes. El wiki no señala mucho al respecto, excepto que dice que existen; No como son diferentes.

Sumado a esta confusión, está el hecho de que esencialmente cada pieza de documentación parece cubrir uno solo de ellos (y generalmente en un contexto RoR). Además, estas opciones no parecen totalmente incompatibles entre sí en una inspección más cercana, en el sentido de que, si entendí esto correctamente, pueden comprender los archivos de cada uno en gran medida.

¿Alguien aquí podría dar una explicación / descripción rápida y precisa de estas bibliotecas, y describir la diferencia entre ellas? Algunos consejos sobre el rendimiento también serían bienvenidos, si está al tanto de alguno (además de los de los documentos fast_gettext, lo cual no tiene sentido considerando mi falta de comprensión de la diferencia entre estas opciones).


I18n es una corriente principal.

R18n es una alternativa con algunas características adicionales (traducciones de modelos, sintaxis de azúcar) y alguna diferencia en ideología y arquitectura (extensibilidad flexible por filtros potentes).

G18n necesita agregar modelos de transición a I18n.

Padrino no es una biblioteca i18n, es solo el marco de trabajo de Sinatra con I18n incorporado.

Gettext es una concepción antigua de IMHO con un formato muy feo y un problema con la pluralización. De todos modos, no es popular en la comunidad Ruby.


La respuesta de Andrey me indicó que regresara a los documentos R18n , que básicamente lo dividen en una sola línea:

R18n utiliza el formato YAML jerárquico y no centrado en el inglés para las traducciones de forma predeterminada.

Encontré este slideshare de Andrey. Está en ruso, pero ahora tiene mucho más sentido (diapositivas 7 a 9, en particular, diferencias claras entre i18n y r18n):

http://www.slideshare.net/iskin/r18n


Primero:
Como escribió Svenfuchs, I18n es un marco que proporciona módulos para muchos enfoques de traducción e internacionalización.
'gettext' es solo uno de los muchos módulos.

Así que realmente no hay duda de usar I18n .

La configuración predeterminada de una aplicación de Rails es usar I18n con el backend de YAML y entiendo parte de su pregunta para comparar ese backend con otros.

En mi humilde opinión, hay dos diferencias principales entre los enfoques basados ​​en gettext y YAML :

  • soporte del ciclo de vida
  • jerarquía

gettext

Una idea de gettext es que traducir una aplicación no es un evento singular, sino un proceso de ciclo de vida.
Está construido para soportar este ciclo en vivo.

gettext está diseñado para utilizar el inglés simple como las claves para las traducciones. Entonces, la idea es escribir la aplicación en inglés y marcar todo el texto que se va a traducir, normalmente envolviéndolo con _() .
Como resultado, el código fuente de la aplicación se puede leer fácilmente en inglés.

Luego, un programa escanea todo el código fuente y extrae los textos para traducir y construye un repositorio (el archivo .pot ) de estos textos.

En el siguiente paso, y aquí viene el ciclo en vivo , el repositorio se fusiona con las traducciones existentes (archivos .po , uno para cada idioma de destino) y se marcan los elementos nuevos o modificados.

Los editores maduros apoyan a los traductores al centrarse en los elementos nuevos y modificados. Además, los diccionarios específicos del proyecto pueden admitir traducciones automáticas parciales.

gettext es plano , lo que significa que cada frase clave se traduce exactamente una vez en los archivos de traducción. No hay jerarquía. Pero hay contexto. En los archivos de traducción, se enumeran todas las posiciones del código fuente de una frase clave. Un editor con acceso al código fuente puede mostrar la fuente junto con la traducción (y algunos lo hacen).

Finalmente, los archivos .po se traducen a formularios de acceso rápido legibles por máquina (pueden ser .mo , el estándar clásico, una base de datos o json o ...)

YAML

YAML y la otra parte es jerárquica, por lo que es fácil tener variaciones de traducciones en diferentes contextos.
I18n utiliza esta estructura para admitir scopes y utiliza la ruta del archivo actual como ámbito cuando se usan claves que comienzan con un punto.
No hay información, donde se usa una clave en el proyecto (bueno, a menos que sea de ámbito automático, pero la clave se puede usar en otros lugares explícitamente).
No hay información, si hay algún cambio.
A menos que su IDE lo apoye, el desarrollador tiene que encontrar el lugar correcto para colocar una clave en el YAML y buscar el uso puede ser engorroso. Mucho más se dice en las otras respuestas.

I18n

Intencionalmente dije YAML y no I18n , porque I18n es un marco para la internacionalización (no solo traducción), y YAML es solo un backend posible.
El soporte plural en I18n difiere del soporte plural de getilla gettext. No tengo experiencia en cómo cooperan.

Ejemplos

Obtener texto con parámetros posicionales:

sprintf(
_('Do you really want to delete tour %1$s_%2$s? Only empty tours can be deleted!'),
tag, idx)

las traducciones son archivos de texto, pero los editores de PO proporcionan GUI:

#: js/addDelRow.js:15
msgid "" "Do you really want to delete tour %1$s_%2$s? Only empty tours can be deleted!" 
msgstr "" "Wollen sie die Spalte %1$s_%2$s wirklich löschen? Nur leere Spalten können "
"gelöscht werden."

YAML con parámetros:

Fuente

<%= t('.checked_at', ts: l(checked_at), user: full_name) %>

traducción
desde

en:
  hotels:
    form:
      checked_at: set to checked by %{user} on %{ts}“

a

de:
  hotels:
    form:
      checked_at: "geprüft gesetzt am %{ts} von %{user}“

Conclusión

Para empezar, YAML es mucho más fácil, especialmente si cuenta con el soporte de un IDE.
Vanilla RAILS lo tiene incorporado.
El no es idioma nativo . La primera traducción puede ser cualquier idioma. Con proyectos en crecimiento y múltiples idiomas, mis archivos YAML tienden a repetirse (la misma traducción dispersa en toda la jerarquía) y rastrear los cambios y, por lo tanto, las nuevas traducciones son engorrosas.

gettext necesita una cadena de herramientas adicional y, por lo tanto, una configuración más difícil.
Es compatible con todo el ciclo de vida de la traducción continua de aplicaciones en desarrollo.
Se basa en el código fuente en inglés.

Usualmente uso las mejores partes de ambos, utilizando YAML para la internacionalización (número y formato de fecha, ¿quizás nombres de modelo?) Y gettext para la traducción.





padrino