Expo-flags

Photo by Cesarexpo (wikimedia.org)

Gettext es un conjunto de herramientas gratuito que facilita a los programadores la creación de interfaces multi-idioma. Es compatible con la mayoría de lenguajes de programación y simplifica en gran medida el proceso de implementar y gestionar las traducciones de los textos de una aplicación o web. En este artículo hablaré de 2 herramientas indispensables para trabajar con este sistema.

Introducción a Gettext

Los que seguís este blog ya sabréis que no me gusta nada dar rodeos y que soy partidario de darle una orientación práctica a todo lo que escribo, pero si os interesa conocer los detalles de Gettext podéis visitar la web de GNU y leer su manual completo.

Gettext utiliza para cada idioma dos archivos: un archivo con extensión .po que contiene los pares de cadenas original-traducción, pensado para ser leído y editado por humanos (Portable Object), y un archivo con extensión .mo que es la conversión binaria del archivo .po y que será la que lea la máquina (Machine Object).

Ejemplo de archivo .po:

msgid "Texto original"
msgstr "Texto traducido"

msgid "Prueba de texto en castellano"
msgstr "Test text in English"

También se suele utilizar un solo archivo con la extensión .pot para diferenciar al que solo contiene los textos originales, sin traducciones, y que servirá de plantilla para crear los .po de cada idioma.

 

Adaptar nuestro código

La extensión Gettext está normalmente incluida, entre otros, en lenguajes de programación tan populares como C, C++, Objetive C, Python, Java, Perl o PHP. Para hacer uso de ella solo hay que modificar la salida de texto, haciéndolo a través de la función gettext a la que le pasaremos como parámetro el texto a mostrar. Por ejemplo, en PHP:

<?php
echo(gettext("Prueba de texto en castellano"));
?>

Para simplificar y dado el carácter estándar de gettext, podemos hacer la llamada directamente utilizando _($texto):

<?php
echo(_("Prueba de texto en castellano"));
?>

Esto es todo lo que tendríamos que cambiar en nuestro código para permitir a nuestra aplicación o página web mostrar el texto en diferentes idiomas. Bueno, casi todo: luego habría que configurar Gettext para hacerle saber qué idiomas hay disponibles y dónde están los archivos de cada uno.

 

Generar el archivo .pot

Aquí es donde entra en acción nuestra primera herramienta imprescindible, xgettext, utilidad con la recopilaremos todos los textos a traducir y con la que crearemos el archivo .pot.

Para los de windows como yo, hay disponible una versión aquí.

Eso sí, no hay GUI así que independientemente del sistema operativo ¡toca abrir la consola!

Después de instalar, localizamos el directorio de instalación (por defecto Program Files (x86)\GnuWin32\bin) y creamos en ese mismo directorio un archivo en blanco llamado messages.po. Escribimos en la línea de comandos lo siguiente:

C:\Program Files (x86)\GnuWin32\bin>xgettext --language=PHP -j messages.po C:\xampp\htdocs\gettextexample\index.php

Si todo ha ido bien, si abrimos el archivo messages.po con un editor de texto veremos:

# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-12-16 09:01+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"

#: C:\xampp\htdocs\gettextexample\index.php:2
msgid "Prueba de texto en castellano"
msgstr ""

Es recomendable rellenar los datos de la cabecera del archivo, en especial el charset (utf-8 o iso-8859-1 por ejemplo).

Si tuviéramos más archivos repetiríamos la operación pasando como argumento los demás nombres (admite comodines, por lo que si están todos en el mismo directorio podemos escribir *.php).

Como este archivo es el master, podemos renombrarlo a messages.pot para reconocerlo como plantilla para crear los archivos .po de cada idioma.

 

Crear y traducir los archivos de cada idioma

Es hora de descargar nuestra segunda herramienta imprescindible: Poedit, disponible en Windows, MacOsX y Linux.

Una vez instalada la abrimos y clicamos en Archivo->Nuevo catálogo desde un archivo POT…

poedit_catalogo_pot

Rellenamos los datos necesarios, haciendo hincapié en el Juego de caracteres y en el Idioma, pulsamos Aceptar.

poedit_catalogo_pot_2

Grabamos el archivo en el directorio correspondiente a la abreviatura del nombre del idioma (en este caso /locale/en_US/LC_MESSAGES/messages.po).

poedit_catalogo_pot

Ya tenemos el archivo creado y listo para traducir. En la parte superior de la pantalla aparecen todos los textos disponibles para traducir. Seleccionando uno de los textos con el ratón se activa la caja de texto Translation de abajo del todo y en la que podemos escribir la traducción.

poedit_catalogo_pot_4

Una vez terminado el proceso, pulsamos en el botón Guardar y el programa generará el archivo .mo correspondiente.

Repetiremos el proceso para todos los idiomas que necesitemos.

 

Configurar Gettext

En cada lenguaje de programación será diferente. Tomaremos como ejemplo en PHP para al menos dejar constancia del proceso.

<?php 
$idioma = (isset($_GET["language"])) ? trim(strip_tags($_GET["language"])) : "es_ES";
putenv("LANG=$idioma");
putenv("LC_ALL={$idioma}");
setlocale(LC_ALL, $idioma);

if (false === function_exists('gettext'))
{
    echo "No tienes la libreria gettext instalada.";
    exit(1);
}

// Define la ubicación de los ficheros de traduccion
bindtextdomain("messages", "./locale");
bind_textdomain_codeset('messages', 'utf-8');
textdomain("messages");

//Mostramos el texto
echo(gettext("Prueba de texto en castellano"));
?>

Si no le pasamos un parámetros por GET obtendremos el texto por defecto, mientras que si le pasamos en_US o fr_FR obtendremos los textos traducidos.

Por si os quedan dudas de la estructura de las carpetas, el proyecto de ejemplo está disponible para descargar en Github.