Este documento explica como dar soporte básico de internacionalización en una aplicación Ruby on Rails utilizando gettext, basándome en el artículo Using Gettext To Translate Your Rails Application.
Se supone que ya se sabe como instalar y utilizar rails, por lo que no lo explico aquí, si fuera necesario existen multitud de manuales.
Tabla de contenidos |
[editar] Instalación de Gettext
Gettext es un conjunto de herramientas libres para la internacionalización de aplicaciones. Aquí nos va a servir para sustituir cadenas de texto escritas en el idioma de desarrollo por el idioma de los usuarios.
Gettext extá escrito en C, pero tiene soporte para todos los lenguajes medianamente extendidos, como Ruby.
Instalarlo es muy simple, ya que estas librerías suelen acompañar a todas las distribuciones de linux, y su uso está muy extendido, de hecho es probable que si usas Linux, ya tengas Gettext instalado.
En un sistema Debian/Ubuntu, puedes instalar el soporte de Gettext para Ruby con apt-get:
$ sudo apt-get install libgettext-ruby-util
Por supuesto también se puede instalar en cualquier plataforma utilizando rubygems:
$ sudo gem install gettext
Una vez instalado ya podemos empezar a modificar nuestra aplicación.
Gettext utiliza para traducir unos ficheros que habitualmente contienen una extensión .mo, el proceso de generar esos ficheros consiste a grandes rasgos en los siguientes pasos:
- Indicar qué textos queremos traducir.
- Generar el archivo de traducciones "fuente" (.pot) escaneando todos los archivos de nuestra aplicación.
- Traducir. (.po)
- Compilar el archivo de traducción (.mo)
También será necesario importar las librerías que dan soporte a estas funciones.
[editar] Modificando nuestra aplicación
[editar] Archivos y directorios
Las aplicaciones traducidas usando Gettext suelen contener las traducciones "fuente" en un directorio po/, hemos de crearlo dentro del directorio raiz. Contendrá una estructura como la siguiente:
$ tree po po |-- es_ES | `-- aplicacion.po `-- aplicacion.pot
Por ahora simplemente crearemos el directorio po, el resto de archivos ya veremos como se genera.
También es convenierte modificar el archivo Rakefile para aprovechar las utilidades de ruby para estas tareas. Añadiremos al final del fichero las siguientes líneas:
require 'gettext/utils' desc "Create mo-files for L10n" task :makemo do GetText.create_mofiles(true, "po", "locale") end
desc "Update pot/po files to match new version."
task :updatepo do
MY_APP_TEXT_DOMAIN = "aplicacion"
MY_APP_VERSION = "aplicacion 0.1"
GetText.update_pofiles(MY_APP_TEXT_DOMAIN,
Dir.glob("{app,lib}/**/*.{rb,rhtml}"),
MY_APP_VERSION)
end
De este modo creamos dos nuevas tareas para rake.
- rake makemo compilará todos los archivos de traducciones que encuentre en po/ y los almacenará en el directorio locale, que tiene una estructura muy similar.
- rake updatepo recorrerá todos los archivos fuente (*.rb y *.rhtml) localizando las cadenas de texto traducibles y actualizando o generando si no existen los archivos de traducciones fuente (.pot y .po).
[editar] Indicar los textos que queremos traducir
Siempre que queramos que un texto pueda ser traducido lo sustituiremos por una llamada a la función gettext recibiendo como parámetro la cadena a traducir. Por ejemplo si tenemos en una plantilla algo como:
<%= "%d metres" % @thing.length %>
podemos marcarlo así:
<%= gettext("%d metres") % @thing.length %>
O mejor aún, utilizando la función "_" que es equivalente a gettext:
<%= _("%d metres") % @thing.length %>
De este modo, siempre que llamemos a gettext, buscará la cadena en cuestión en los archivos de traducciones compiladas .mo y si existe una traducción la devolverá.
Llegados a este punto quedan un par de cabos sueltos. Hay que importar las funciones gettext y _ y hay que decirle a que idioma queremos que traduzca.
Tenemos que importar en app/controllers/application.rb gettext para rails:
require 'gettext/rails'
e inicializar la librería utilizando init_gettext:
class ApplicationController < ActionController::Base init_gettext "aplicacion" ... end
Es importante que utilicemos el mismo dominio que definimos en Rakefile (MY_APP_TEXT_DOMAIN).
Con esta configuración nuestra aplicación intentará traducir al idioma que le especifique el navegador cliente. Si no tenemos traducción para el idioma solicitado, gettext mostrará las cadenas en el idioma original.
Este comportamiento por defecto puede ser alterado especificando otro idioma en el campo "lang" de QUERY_STRING o de la Cookie o con GetText.bindtextdomain.
[editar] Generar el archivo fuente
Una vez que hemos indicado todas las cadenas que queremos traducir en nuestra aplicación podemos usar rake para crear el fichero .pot:
$ rake updatepo
Este comando además añadirá otras cadenas indicadas por rails para que las traduzcamos y comprobará que los archivos de traducciones de cada idioma contenga las mismas entradas que el archivo raíz.
[editar] Traducir
Para cada traducción hemos de crear un subdirectorio en po/ con el identificador internacional de idioma y copiar allí el archivo .pot con extensión .po, por ejemplo:
$ mkdir po/es_ES $ cp po/aplicacion.pot po/es_ES/aplicacion.po
El archivo .po podemos traducirlo con algún programa asistente como gtranslator o directamente editándolo desde cualquier editor de textos. Si se abre con un editor de texto se ve una secuencia de tríos de cadenas de texto similares a esta:
... #: app/models/location.rb:- msgid "location" msgstr "ubicación" ..
La primera línea especifica en que archivo se ha encontrado la cadena de texto, msgid es la cadena tal y como se encuentra en los fuentes (como parámetro a una llamada a gettext) y msgstr la traducción.
[editar] Compilar los archivos de traducción
Finalmente tan solo tenemos que ejecutar el siguiente comando:
$ rake makemo
Que generará los archivos .mo y a disfrutar de aplicación internacionalizada :)