Aplicaciones multilingües, gettext
A menudo se piensa que una aplicación estaría mucho mejor si se encontrara en varios idiomas. Podemos pensar en distintas formas de soportar esto, pero otros ya lo han pensado por nosotros y han creado las fabulosas herramientas gettext. Este documento pretende ser una guía para el uso rápido (rápido de verdad) de estas herramientas.
Notas
Esta receta se publicó por primera vez en Crysol, pero a partir de ahora estará aquí la última versión, si decido modificarla.
Como yo fui el autor de la receta original, no estoy haciendo plagio :-D
Ingredientes
- gettext
Modificaciones en el código
Lo primero es acordarse de evitar cadenas sin más (al menos las que se muestran) en nuestro código. Ahora importaremos la librería gettext y utilizaremos la función gettext. Se encuentra disponible para numerosos lenguajes, aunque aquí se explicará con ejemplos en python (las diferencias serán mínimas en el resto de lenguajes).
En Python queda así:
|
|
No os asustéis: Las funciones textdomain
y bindtextdomain
sirven para decirle a gettext dónde se encuentran las traducciones. Aquí se está
poniendo un ejemplo, así que sustituid programita
por el nombre de vuestro
programa, y ./mo
por el directorio donde vamos a meter las traducciones.
A menudo, además, se suele importar la función gettext cambiándole el nombre a
algo más sencillo como la barra baja. De esta manera, nos evitamos tener que
escribir gettext.gettext
cada vez. Para hacer esto hay distintas
maneras, una de ellas es durante la importación:
|
|
Generación de la plantilla de traducción (.pot)
Podemos obtener la plantilla del código en casi cualquier lenguaje: C, C++, Python, Perl, Glade, Java, … Y se hace así:
|
|
Las opciones son: --language
indicando el lenguaje del código, y -j
que
indica que, si hay ya un .pot existente, se deben mezclar los mensajes.
Si hemos usado algún cambio y no aparece la función como “gettext”, será
necesario usar también la opción --keyword
. Por ejemplo:
|
|
Ale, ya tenemos el messages.pot.
Generar el fichero de traducciones (*.po)
Ahora se utiliza el messages.pot para generar cada plantilla. Nosotros queremos la traducción al castellano, así que será es.po:
|
|
Ahora viene la parte en la que editamos el fichero es.po (yo suelo usar gtranslator o kbabel) y demás.
Mezclar el fichero de traducciones (*.po) con una nueva plantilla (*.pot)
Este sistema sería poco eficiente si tuviéramos que traducirlo todo de nuevo cada vez que se cambie el fuente. Por ello, hay un sistema por el que se mezcla el fichero ya traducido con la plantilla nueva (es decir: volvemos al paso de creación de plantilla y después ejecutamos esto):
|
|
Y, nuevamente, volvemos a traducir :-D
Creación del fichero de equivalencias (*.mo)
Realmente, el ficherito .po
no se utiliza en el ejecutable. Es necesario
utilizar un ficherito .mo
. Aquí crearemos nuestro es.mo
, como es lógico:
|
|
Como podéis observar, el resultado lo dejamos en mo/es/LC_MESSAGES/
. Eso lo
hacemos así porque en el código fuente dijimos que las traducciones colgarían
del directorio mo
, el idioma es Español (las locales son “es”), y porque todos
los .mo
deben colgar de un directorio LC_MESSAGES
dentro de las locales para
que sea encontrado correctamente.
Utilización
Ya está. No hay nada más que contar. Si las locales son es
, escribirá nuestra
traducción, y si son en
, lo escribirá en inglés. Eso es todo.
Ejemplo
Veamos un ejemplo, sugerencia hecha por david.villa:
|
|
Como requisito, necesitaremos el directorio donde vamos adejar las cosas. En el
código hemos puesto ./mo
, así que hay que ser consecuentes:
|
|
Ahora inicializamos (llamaremos al .pot
“messages.pot”):
|
|
Y generamos nuestro primer .po:
|
|
Editamos el archivo es.po que se nos habrá creado, traduciendo la única cadena. Mi archivo pinta así:
# Spanish translations for PACKAGE package.
# Copyright (C) 2010 THE PACKAGE''S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# miguel <miguelangel.garcia@gmail.com>, 2010.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\
"
"Report-Msgid-Bugs-To: \
"
"POT-Creation-Date: 2010-05-25 07:31+0200\
"
"PO-Revision-Date: 2010-05-25 07:32+0200\
"
"Last-Translator: miguel <miguelangel.garcia@gmail.com>\
"
"Language-Team: Spanish <>\
"
"MIME-Version: 1.0\
"
"Content-Type: text/plain; charset=ASCII\
"
"Content-Transfer-Encoding: 8bit\
"
"Plural-Forms: nplurals=2; plural=(n != 1);\
"
#: hello.py:12
msgid "hello, world!"
msgstr "hola, mundo!"
Por ahora no nos fijaremos mucho en las cosa que deberíamos cambiar, como el PACKAGE y demás. Sólo nos queda compilar:
|
|
y probarlo:
|
|
¡¡Gracias, David, por tu propuesta!!