Categorías: Labs

Localizando apps para Firefox OS

Esta es una traducción del artículo original publicado en el blog de Mozilla Hacks. Traducción por Julián Aragón.

Las apps para Firefox OS se utilizan en todo el mundo – España, Polonia, Colombia y Venezuela con muchos más países en camino – por lo que es importante considerar desde el principio localizar tu app. Pero con la web abierta como es, existen muchos frameworks y tecnologías entre los que elegir en lo que se refiere a localización. Por ejemplo, la librería estilo Gettext Jed es una opción tradicional y popular. Además hay nuevas plataformas de localización en desarrollo que amplían las capacidades disponibles en las librerías actuales. Por ejemplo, en Mozilla tenemos un proyecto de localización muy prometedor que amplía L10n con una variedad de nuevas características atractivas. Para aprender más sobre ello, echa un vistazo al grupo Mozilla Tools.

En este artículo discutiremos cómo localizar tu app para Firefox OS usando las librerías empleadas actualmente para localización en la capa Gaia de Firefox OS. Gaia incluye todas las apps en el sistema operativo, incluyendo el marcador de teléfono y el administrador de contactos, por lo que proporciona un buen modelo a imitar. Sin embargo, si decides usar éste método, ten en mente que algunas de las funciones de la librería (por ejemplo l10n_date.js utiliza un método toLocaleFormat no estándar) no son compatibles entre navegadores, y que Gaia migrará probablemente a L20n en el futuro.

L10n.js

Actualmente Firefox OS Gaia utiliza una versión modificada de la librería L10n.js de Fabien Cazenave para localizar las apps que están disponibles por defecto en Firefox OS. Se encuentra disponible en el repositorio de fuentes de Gaia. La librería se basa en archivos de propiedades con formato clave / valor. El analizador sintáctico (parser) de L10n.js también soporta la importación de reglas que pueden utilizarse para la selección del lenguaje en el lado cliente. Las apps por defecto de Gaia utilizan un archivo ini para especificar la declaración de importaciones y una etiqueta enlace para cargar el archivo ini.

Como ejemplo de su funcionamiento, examina la app de Bluetooth, que puede usarse para transferir archivos. Los archivos de propiedades de la app están estructurados de la siguiente manera.

Archivos de app bluetoothEsta app contiene archivos de propiedades para cuatro localizaciones (ar, en-US, fr, y zh-TW). Una parte del archivo de propiedades en-US se muestra a continuación:

bluetooth = Bluetooth
confirmation = Confirmation
bluetooth-status-description = Bluetooth is disabled
turn-bluetooth-on = Do you want to turn Bluetooth on?
cancel = Cancel
turn-on = Turn On

Como puedes ver, es un archivo simple de propiedades clave / valor con las cadenas de texto a localizar. Todos estos archivos se almacenan en el directorio locales de la app de Bluetooth. Además, esta carpeta contiene un archivo locales.ini con el siguiente contenido:

@import url(bluetooth.en-US.properties)
 
[ar]
@import url(bluetooth.ar.properties)
 
[fr]
@import url(bluetooth.fr.properties)
 
[zh-TW]
@import url(bluetooth.zh-TW.properties)

El archivo ini especifica qué archivos de propiedades cargar basado en la localización del usuario de la app. Actúa como un diccionario de multi-regiones listando todas las localizaciones soportadas. Además, en este caso particular, el archivo de propiedades en-US (inglés de Estados Unidos) actúa como la localización por defecto si no se encuentra ningún registro para la localización de un usuario determinado. Este archivo ini se carga utilizando la siguiente sintaxis con la etiqueta link.

<link rel="resource" type="application/l10n" href="locales/locales.ini"/>

El atributo rel se puede establecer también como “prefetch” para precargar el archivo ini y mejorar el rendimiento.

Atributos de elemento de L10n

Definimos elementos que necesitan traducción añadiendo un atributo data-l10n-id, que corresponde a una clave definida en el archivo de propiedades. Por ejemplo, un encabezado que necesite ser localizado puede parecerse a esto:

<h2 data-l10n-id="label1">Label One</h2>

El valor del atributo “label1” sirve de clave dentro del archivo de propiedades. Se pueden crear cadenas de texto más complejas en el archivo de propiedades utilizando sustitución de argumentos y la macro plural.

Sustitución de argumentos

La sustitución de argumentos se consigue rodeando el argumento con llaves dobles {{arg}}. Entonces, se puede personalizar un mensaje para un usuario específico utilizando sintaxis similar a la siguiente:

loginmessage = Hello {{user}}, glad you decided to visit

Se pueden establecer valores por defecto utilizando el atributo data-l10n-args. Este atributo espera un valor JSON formateado. En el ejemplo superior, se puede establecer un valor por defecto para el usuario utilizando el siguiente código HTML:

<h2 data-l10n-id="label1" data-l10n-args='{ "user": "Guest" }'>Label One</h2>

Macro plural

La macro plural se puede utilizar para personalizar mensajes basándonos en el valor de un argumento. La macro toma un valor numérico y devuelve zero (cero), one (uno), two (dos), few (pocos), many (muchos), o other (otro). El valor de retorno depende del valor que se ha pasado y de las reglas de pluralización de Unicode de la localización actual. Por ejemplo, un mensaje de email personalizado para la configuración regional en-US podria parecerse a esto:

mailMessage ={[ plural(n)]}
mailMessage[zero]  = you have no messages
mailMessage[one]   = you have one message
mailMessage[two]   = you have two messages
mailMessage[other]= you have {{n}} messages
<h3 data-l10n-id="mailMessage" data-l10n-args='{ "n": "1" }'>Mensaje</h3>

Script L10n

La mayoría de apps por defecto de Firefox OS utilizan una etiqueta script similar a la siguiente para cargar la librería L10n.js.

<script defer src="/shared/js/l10n.js" charset="utf-8"></script>

Para utilizar esta libreria en tu app, necesitaras copiar el archivo l10n.js a tu proyecto local y cambiar el atributo src.

Una vez cargada, la librería L10n.js mostrará un objeto navigator.mozL10n que puede ser utilizado para localización en el lado cliente.

Los métodos y propiedades más útiles de mozL10n están descritos a continuación.

El método get

El método get se utiliza para obtener una cadena de texto traducida para la localización actual. El método toma un parámetro clave y un parámetro args opcional. El parámetro clave especifica la clave definida del archivo de propiedades.

mozL10n.get("mylabel")

El parámetro args se puede utilizar para pasar un argumento JSON formateado para cadenas de texto que contienen argumentos.

// archivo properties.
welcome = Welcome {{user}}!
// archivo JavaScript.
alert( navigator.mozL10n.get(“welcome”,  { user:"Martin"}));

El método localize

El método localize se puede utilizar para añadir los atributos de L10n a contenido creado dinámicamente. El método toma un elemento, un id, y un parámetro args opcional. El parámetro elemento especifica el elemento a ser localizado. El parámetro id especifica el atributo id L10n que quieres asignar al elemento. El parámetro opcional args te permite crear el atributo data-l10n-args y establecer su valor JSON.

var button2 = document.querySelector("#button2");
if (button2) { 
    button2.onclick = function () {
        var myElement = document.createElement('span');
        var lblTxt = document.createTextNode("My Label");
        myElement.appendChild( lblTxt );
        navigator.mozL10n.localize(myElement, 'label3'{ arg: "myarg" });
        document.body.appendChild(myElement);
    }
};

Esto creará el siguiente código HTML.

<span data-l10n-id="label3" data-l10n-args="{"arg":"myarg"}"> My Label</span>

Además el texto será traducido inmediatamente.

El método ready

El método ready te permite definir una llamada de retorno cuando la localización del documento actual está lista.

var button1 = document.querySelector("#button1");
if (button1) { 
    button1.onclick = function () {                
        navigator.mozL10n.language.code = "fr";
        navigator.mozL10n.ready( function() {
            alert(navigator.mozL10n.get("button1"));
        });        
    }
};

La propiedad language

La propiedad language contiene métodos getter y setter para el código del lenguaje. La propiedad language contiene además un método getter para la dirección del lenguaje para soportar idiomas de derecha a izquierda (Árabe o Hebreo) y de izquierda a derecha.

var mycode = navigator.mozL10n.language.code;
navigator.mozL10n.language.code = "fr";
navigator.mozL10n.language.direction // retorna rtl or ltr

Script L10n_Date

Para manipular fechas y horas, las apps de Gaia aumentan las posibilidades de L10n.js con la libería l10n_date.js. Como la librería l10n.js, implementa algunas funciones que podrían no ser compatibles con todos los navegadores. La libreria se encuentra disponible en el repositorio de fuentes y utiliza la misma estructura de propiedades descrita en la sección L10n.js de este artículo. Todas las apps de Gaia que utilizan esta librería dependen de un conjunto compartido de archivos de propiedades y de un archivo date.ini para importar el archivo de propiedades de la localización específica. El archivo date.ini se encuentra en el repositorio de fuentes de Gaia y los archivos de propiedades específicos para las localizaciones se encuentran en el directorio https://github.com/mozilla-b2g/gaia/tree/master/shared/locales/date. Estos archivos de propiedades definen formatos y cadenas de texto para cosas como el día que en comienza una semana, formatos de fecha cortos y nombres de cada mes. Para utilizar esta librería en tu app, deberás copiar todos los archivos a tu propio proyecto. El archivo ini y los scripts se cargan de manera similar a la librería L10n.js.

<link rel="resource" type="application/l10n" href="locales/date.ini" />
<script defer src="js/l10n_date.js"></script>

Cuando utilicemos los métodos de la librería L10n_date, las cadenas de texto en los archivos de propiedades pueden usar códigos de formato fecha/hora estándar de C++. Como ejemplo de esto, examina el archivo de propiedades de la app reloj de Gaia.

Este archivo contiene el siguiente registro para dateFormat para la configuración regional en-US.

dateFormat = %A,%B %e

Utilizando el método formatLocale que se encuentra dentro de la librería L10n_Date, éste devolverá:

“Nombre completo del día de la semana” “Nombre completo del Mes” “Día del mes” (Thursday January 29). La versión francesa del archivo de propiedades define la misma clave de la siguiente manera.

dateFormat = %A %e %B

Esto da como resultado:

“Nombre completo del día de la semana” “Día del mes” “Nombre completo del mes” (jeudi 25 janvier).

Cuando incluyes la librería L10n_Date, se encuentra disponible un nuevo método para el objeto mozL10n (navigator.mozL10n.DateTimeFormat()). Una vez instanciado, este objeto tiene varios métodos que pueden ser utilizados para localizar fechas. Los más utiles son:

El método localeFormat

El metodo localeFormat method toma como parametro un objeto de tipo fecha y un patrón de formato y devuelve la fecha formateada tal y como el patrón especifica. Este método debería usarse junto con el método get de L10N.js para formatear una fecha localizada.

button3.onclick = function () {
    navigator.mozL10n.language.code = "fr";
    navigator.mozL10n.ready( function() {
        var d = new Date();
        var f = new navigator.mozL10n.DateTimeFormat();
        var format = navigator.mozL10n.get('dateFormat');
        var formatted = f.localeFormat(d, format);
        alert( formatted );
    });    
}

Los métodos localeDateString, localeTimeString y localeString

Estos tres métodos son simplemente variaciones del método localeFormat que devuelve fechas formateadas basándose en los siguientes valores clave dentro del archivo de propiedades.

//en-US
//localeString retorna
dateTimeFormat_%c = %a %b %e %Y %I:%M:%S %p
//localeDateString retorna
dateTimeFormat_%x = %m/%d/%Y
//localeTimeString retorna
dateTimeFormat_%X = %I:%M:%S %p

El método fromNow

El método fromNow recibe un parámetro fecha/hora y devuelve una cadena de texto formateada acorde a la localización, expresando la diferencia entre la fecha/hora actual y la fecha/hora pasada como parámetro. La cadena de texto formateada se basará en las cadenas de texto definidas en el archivo propiedades de fechas. Por ejemplo:

// ejecutado en 25/07/2013 12:11:00
var d = new Date("July 25, 2013 11:13:00");
var f = new navigator.mozL10n.DateTimeFormat();
alert( f.fromNow(d));

Alertará “58 Minutes Ago” (“hace 58 minutos”) en la localización en-US. La cadena de texto será formateada usando la clave minutes-ago-long en el archivo propiedades de fechas.

minutes-ago-long={[ plural(value)]}
minutes-ago-long[zero]= just now
minutes-ago-long[one]= a minute ago
minutes-ago-long[two]={{value}} minutes ago
minutes-ago-long[few]={{value}} minutes ago
minutes-ago-long[many]={{value}} minutes ago
minutes-ago-long[other]={{value}} minutes ago

¡Aprende más e involucrate!

Para más información / lectura complementaria sobre buenas prácticas de localización, lee el artículo de Mozilla Developer Network, “Creando aplicaciones web localizables.”

Y una vez hayas terminado de localizar tu propia app para Firefox OS, ¿Por qué no ayudar con la localización de Firefox OS? Echa un vistazo a este enlace para más información sobre cómo contribuir.

The following two tabs change content below.

jorgev

Add-ons Developer Relations Lead at Mozilla
Jorge trabaja para el equipo de complementos de Mozilla, y se dedica a Mozilla Hispano y Mozilla Costa Rica en su tiempo libre. Actualmente está encargado del blog de Mozilla Hispano Labs.