Changes between Initial Version and Version 1 of Version2/Tutoriales/Consola_Web/Tutorial_3_Internacionalizacion


Ignore:
Timestamp:
Aug 17, 2010, 2:05:42 PM (14 years ago)
Author:
adelcastillo
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Version2/Tutoriales/Consola_Web/Tutorial_3_Internacionalizacion

    v1 v1  
     1= Internacionalización de plugins =
     2== Introducción ==
     3
     4En este tutorial sobre Opengnsys 2 vamos a explicar el funcionamiento de las traducciones de los plugins para la Consola Web.
     5
     6Los plugins de la consola web pueden ser internacionalizables, lo que implica que podrán ser utilizados por diferentes usuarios en diferentes idiomas a un bajo coste programático, es decir, que utilizando las funcionalidades que la consola web nos ofrece para internacionalizar, traducir un plugin y utilizarlo en otro idioma no supone ningún esfuerzo adicional.
     7
     8Para la internacionalización se utiliza la herramienta [http://es.wikipedia.org/wiki/Gettext gettext], utilizada ampliamente en multitud de proyectos. El uso de gettext consiste básicamente en escribir todas las cadenas del código en inglés, pero pasadas a través de una función que se encargará de coger la cadena correspondiente en caso de estar viendo otro idioma. Normalmente en código se utiliza la función _() y es común ver líneas de código con cadenas como _("hello world!").
     9
     10== Utilizando i18n en las vistas ==
     11
     12Para facilitar la internacionalización de los plugins, la consola web ofrece un decorador python (pi18n), que lo único que hace es añadir la variable global '''_''' al contexto de la función decorada.
     13
     14Los decoradores python son modificadores de funciones, y para su utilización se suelen poner con @nombre_decorador justo encima de la definición de la función o método que queremos decorar.
     15
     16En concreto, la consola web ofrece dos decoradores para las traducciones, dentro del módulo decorators, '''i18n''' y '''pi18n'''. El primero se usa para las traducciones propias de la consola web, y en teoría no es necesario utilizarlo en los plugins, y el segundo es el indicado para usar en las vistas y funciones de los plugins.
     17
     18Todo esto puede parecer complicado, pero en la práctica es mucho más simple, no es necesario comprender cómo funcionan los decoradores de python ni cómo funciona gettext. Veámoslo con un ejemplo:
     19
     20{{{
     21import web
     22from decorators import pi18n
     23
     24class HelloView:
     25    @pi18n
     26    def GET(self):
     27        return web.ctx.render.plugins.hello_world.helloview(_('Hello World!'))
     28}}}
     29
     30En el código de esta vista del plugin hello_world se puede observer cómo importamos '''pi18n''' del módulo '''decorators''' y luego cómo se utiliza en la vista, decorando el método GET, situando '''@pi18n''' justo antes de su definición. Luego, dentro de la función hacemos uso de '''_()''' que es la variable que introduce el decorador dentro del contexto de la función. Toda cadena traducible debe ir dentro de '''_()'''.
     31
     32Es así de simple, importar pi18n, decorar la vista con cadenas internacionalizables y pasar toda cadena por la llamada '''_()'''.
     33
     34== Utilizando i18n en los templates ==
     35
     36Los templates de los plugins también son internacionalizables, por lo tanto también se pueden escribir cadenas traducibles dentro de los templates html.
     37
     38En los templates es aún más fácil hacer uso de la internacionalización, porque la función la está en el contexto y tan sólo hay que utilizarla. Para los templates también existen dos funciones de internacionalización, '''_()''' y '''_p()''', la primera es para la internacionalización del core de la consola web, y la segunda es para traducciones de plugins. En principio en una plantilla de un plugin sólo se debería usar '''_p()''', aunque es posible utilizar '''_()''', pero sólo es recomendable para aquellos que sepan lo que están haciendo.
     39
     40Por lo tanto, para traducir cadenas dentro de un plugin lo que hay que hacer es meter esta cadena dentro de la función '''_p()'''. Veamos un ejemplo:
     41
     42{{{
     43$def with ()
     44$var title = _p("Hello World!")
     45$var tab: panel
     46$var hierarchy = []
     47
     48$code:
     49    h = "hola hola"
     50    long_text = _p("Hello world, this is a multiline text, "
     51                             "that i'm writting in a template "
     52                             "multiline should be inside a code sentence "
     53                             "and  asigned to a variable that you can use "
     54                             "later. Also you can use string operations like %(hello)s") % {'hello': h}
     55
     56<p>
     57$_p("Hello World!")
     58</p>
     59<p>
     60$long_text
     61</p>
     62}}}
     63
     64En este ejemplo se puede ver el uso de '''_p''', para texto largo o compuesto a través de código python se puede utilizar $code. Dentro de $code todo es código python, por lo tanto no hace falta poner el $ delante de la llamada a '''_p'''.
     65
     66== Generando ficheros .po ==
     67
     68Una vez tenemos el plugin internacionalizado, con todas las cadenas pasadas por las funciones '''_()''' en las vistas y '''_p()''' en los templates, podemos generar los ficheros .po para los idiomas que queramos.
     69
     70Lo primero es crear el directorio '''i18n''' dentro de tu plugin. Por ejemplo, si nuestro plugin está en plugins/hello, debemos crear plugins/hello/i18n. Dentro de '''i18n''' debe existir una carpeta por cada idioma al que queramos poder traducir. Supongamos que queremos el español, pues creamos la carpeta '''es''' dentro de '''i18n''':
     71
     72{{{
     73$ cd plugins/hello/
     74$ mkdir -p i18n/es
     75$ cd ../..
     76}}}
     77
     78Una vez creadas todas las carpetas de idiomas, se pueden generar los .po simplemente llamando al script '''i18n_extract_plugin.sh'''.
     79
     80{{{
     81$ ./i18n_extract_plugin.sh plugins/hello
     82}}}
     83
     84Esta llamada generará tantos ficheros .po como directorios haya dentro de i18n. En nuestro caso, se creará el fichero plugins/hello/i18n/es/LC_MESSAGES/messages.po
     85
     86== Traduciendo ==
     87
     88Los ficheros .po son muy simples y hay muchas herramientas para trabajar con ellos. Básicamente consisten en pares de cadenas, la original y la traducida debajo, con una serie de metadatos al principio del fichero, que indican el autor, codificación, etc.
     89
     90Para traducir se puede utilizar cualquier editor de textos, pero es recomendable utilizar una herramienta específicia para este tipo de ficheros, como por ejemplo [http://www.poedit.net/ poedit].
     91
     92== Generando traducciones (.mo) ==
     93
     94Los ficheros de traducciones .po se compilan a binario .mo por temas de eficiencia. Así pues la aplicación utiliza los ficheros .mo generados a partir de los .po para traducir.
     95
     96Para compilar las traducciones de un plugin se puede utilizar el script '''i18n_make_plugin.sh''', ten en cuenta que antes de llamar a este script hay que  haber realizado los pasos anteriores para tener los ficheros .po ya traducidos.
     97
     98{{{
     99$ ./i18n_make_plugin.sh plugins/hello
     100}}}
     101
     102Esta llamada generará los ficheros .mo para cada idioma dentro de la carpeta i18n del plugin hello, en nuestro caso, como sólo tenemos el directorio es, se generará el fichero plugins/hello/i18n/es/LC_MESSAGES/messages.po
     103
     104== Actualizando las traducciones ==
     105
     106Si hemos hecho cambios en el código o queremos añadir una nueva traducción después de tener las traducciones generadas podemos regenerarlas para que incluyan las nuevas cadenas. El procedimiento es el mismo que cuando no hay traducciones, primero hay que ejecutar el script '''i18n_extract_plugin.sh''' que cogerá las cadenas nuevas y las mezclará con las existentes en el fichero .po. Si se ha añadido un nuevo directorio dentro de i18n, por ejemplo fr, el script generará el fichero .po correspondiente.
     107
     108Una vez actualizados los ficheros .po hay que compilar, de la misma manera que antes, ejecutando el script '''i18n_make_plugin.sh'''