El libro de Django 1.0

18.7. Traducciones y JavaScript

El agregar traducciones a JavaScript plantea algunos problemas:

  • El código JavaScript no tiene acceso a una implementación de gettext.
  • El código JavaScript no tiene acceso a los archivos .po o .mo; los mismos necesitan ser enviados desde el servidor.
  • Los catálogos de traducción para JavaScript deben ser mantenidos tan pequeños como sea posible.

Django provee una solución integrada para esos problemas: convierte las traducciones a JavaScript, de manera que puedas llamar a gettext y demás desde JavaScript.

18.7.1. La vista javascript_catalog

La solución principal a esos problemas es la vista javascript_catalog, que genera una librería de código JavaScript con funciones que emulan la interfaz gettext más un arreglo de cadenas de traducción. Dichas cadenas de traducción se toman desde la aplicación, el proyecto o el núcleo de Django, de acuerdo a lo que especifiques ya sea en el info_dict o en la URL.

La forma de usar esto es asi:

js_info_dict = {
    'packages': ('your.app.package',),
}

urlpatterns = patterns('',
    (r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict),
)

Cada cadena en package debe seguir la sintaxis paquete separados por puntos de Python (el mismo formato que las cadenas en INSTALLED_APPS) y deben referirse a un paquete que contenga un directorio locale. Si especificas múltiples paquetes, todos esos catálogos son fusionados en un catálogo único. esto es útil si usas JavaScript que usa cadenas de diferentes aplicaciones.

Puedes hacer que la vista sea dinámica colocando los paquetes en el patrón de la URL:

urlpatterns = patterns('',
    (r'^jsi18n/(?P<packages>\S+?)/$', 'django.views.i18n.javascript_catalog'),
)

Con esto, especificas los paquetes como una lista de nombres de paquetes delimitados por un símbolo + en la URL. Esto es especialmente útil si tus páginas usan código de diferentes aplicaciones, este cambia frecuentemente y no deseas tener que descargar un único gran catálogo. Como una medida de seguridad, esos valores pueden solo tomar los valores django.conf o cualquier paquete de la variable de configuración INSTALLED_APPS.

18.7.2. Usando el catálogo de traducciones JavaScript

Para usar el catálogo simplemente descarga el script generado dinámicamente de la siguiente forma:

<script type="text/javascript" src="/path/to/jsi18n/"></script>

Esta es la forma en la que el sitio de administración obtiene el catálogo de traducciones desde el servidor. Una vez que se ha cargado el catálogo, tu código JavaScript puede usar la interfaz estándar gettext para acceder al mismo:

document.write(gettext('this is to be translated'));

Existe incluso una interfaz ngettext y una función de interpolación de cadenas::

d = {
    count: 10
};
s = interpolate(ngettext('this is %(count)s object', 'this are %(count)s objects', d.count), d);

La función interpolate admite tanto interpolación posicional como interpolación con nombres. De manera que el código de arriba podría haber sido escrito de la siguiente manera:

s = interpolate(ngettext('this is %s object', 'this are %s objects', 11), [11]);

La sintaxis de interpolación se tomó prestada de Python. Sin embargo, no debes exagerar con el uso de la interpolación de cadenas — esto sigue siendo JavaScript así que el código tendrá que realizar múltiples sustituciones de expresiones regulares. Esto no es tan rápido como la interpolación de cadenas en Python, de manera que deberías reservarlo para los casos en los que realmente lo necesites (por ejemplo en combinación con ngettext para generar pluralizaciones en forma correcta).

18.7.3. Creando catálogos de traducciones JavaScript

Los catálogos de traducciones se crean y actualizan de la misma manera que el resto de los catálogos de traducciones de Django: con la herramienta make-messages.py. La única diferencia es que es necesario que proveas un parámetro -d djangojs, de la siguiente forma:

$ make-messages.py -d djangojs -l de

Esto crea o actualiza el catálogo de traducción para JavaScript para alemán. Luego de haber actualizado catálogos, sólo ejecuta compile-messages.py de la misma manera que lo haces con los catálogos de traducción normales de Django.