No hay momento mas dulce en el desarrollo de un programa el ver que va tomando solidez y que puedas implantar detallitos interesantes en la generación de pdf, navegar por el programa que va a los sitios que tiene que ir, etc. Hoy vamos a hablar de una de estas otras cosas que señalan el avanzado estado de nuestro programa, la internacionalización, el disponer la página en varios idiomas. Vamos a contarlo!
Primero de todo recomiendo tener a mano la documentación de django y éste otro artículo de Alex Dzul al que le he copiado el título y la metedología.
Para resumir, lo que tendremos que hacer será configurar el settings.py, preparar y traducir la interfaz y finalmente generar los ficheros .po. En la documentación te habla primero de la generación de los ficheros de traducción y después desarrollar la traducción en la interfaz (templates), luego contaré porqué es mejor hacerlo al revés.
Así que empezamos
Primero modificaremos el fichero settings.py de nuestro proyecto
(venv) laura@melatonina:~/dev/colibri$ vi colibri/settings.py import os BASE_DIR = os.path.dirname(os.path.dirname(__file__)) [...] MIDDLEWARE_CLASSES = ( # ... 'django.middleware.locale.LocaleMiddleware', # ... ) [...] # Internationalization # https://docs.djangoproject.com/en/2.1/topics/i18n/ # https://www.pythoniza.me/multiples-idiomas-en-django/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'Europe/Madrid' USE_I18N = True USE_L10N = True USE_TZ = True from django.utils.translation import ugettext_lazy as _ LANGUAGES = ( ('en', _('English')), ('es', _('Spanish')), ('ca', _('Catalan')), ) # Definimos la ruta de los archivos de idiomas LOCALE_PATHS = ( os.path.join(BASE_DIR, 'locale'), ) # Definimos el procesador de contexto para i18n #from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS as TCP #TEMPLATE_CONTEXT_PROCESSORS = TCP + ( # "django.core.context_processors.i18n", # "django.core.context_processors.request", #)
Tengo desactivada la última parte porque me falla y funciona correctamente sin ésta parte.
Ahora crearemos un directorio llamado locale en la raíz de nuestro programa (dónde está el manage.py)
(venv) laura@melatonina:~/dev/colibri$ mkdir locale (venv) laura@melatonina:~/dev/colibri$ ls colibri locale manage.py __pycache__ README requirements.txt scripts venv web
Ahora, según mi experiencia, lo mejor será configurar las plantillas para que se puedan traducir automáticamente las cadenas, para ello, añadiremos el plugin i18n en cada una de las páginas que vayamos a usar la traducción
Al principio de uno de los ficheros de plantilla (.html) tengo algo similar a ésto:
< !-- extend base layout -- > {% extends "base.html" %} {% load views_templates %} {% load i18n %}
A continuación, para cada palabra o string que queramos traducir lo vamos a poner en éste formato:
< strong >{% trans "Status" %}: < /strong > {% trans "Creation date" %} {% trans request.language.name %}
En el primer caso lo vemos entre las etiquetas de negrita, en el segundo que ésta cadena puede disponer de espacios y en el tercero traducimos la salida de la base de datos, en éste caso el nombre del idioma de la sesión del usuario.
Una vez hecho ésto a lo ancho y largo de nuestro código vamos a generar los ficheros de traducción .po, así que volveremos a la raíz de nuestro programa y ejecutaremos lo siguiente:
(venv) laura@melatonina:~/dev/colibri$ django-admin makemessages --locale en
Ésto generará la siguiente estructura:
(venv) laura@melatonina:~/dev/colibri$ tree locale locale ├── en │ └── LC_MESSAGES │ └── django.po 2 directories, 1 file
Si modificamos el fichero veremos que ha añadido muchísimas mas cadenas de las que realmente hemos traducido en nuestro proyecto, y deberemos limpiar el django.po. Dentro de él, nos encontraremos las cadenas que hemos pedido traducir con éste formato:
(venv) laura@melatonina:~/dev/colibri$ vi locale/en/LC_MESSAGES/django.po msgid "Status" msgstr "" msgid "Creation date" msgstr "" msgid "English" msgstr "" msgid "Spanish" msgstr "" msgid "Catalan" msgstr ""
Ahora lo siguiente será crear una estructura similar a ésta, y con las cadenas msgstr traducidas al idioma al que corresponda el .po. Si hemos definido la traducción (django-admin makemessages) en inglés, los strings en Inglés si están en blanco aparecerá la cadena de msgid.
(venv) laura@melatonina:~/dev/colibri$ tree locale/ locale/ ├── ca │ └── LC_MESSAGES │ └── django.po ├── en │ └── LC_MESSAGES │ └── django.po └── es └── LC_MESSAGES └── django.po 6 directories, 3 files
Una vez traducidos los django.po, tendremos que generar los ficheros django.mo (compilados), para ello ejecutaremos lo siguiente:
(venv) laura@melatonina:~/dev/colibri$ django-admin compilemessages
Y la estructura de directorios y ficheros será así
(venv) laura@melatonina:~/dev/colibri$ tree locale/ locale/ ├── ca │ └── LC_MESSAGES │ ├── django.mo │ └── django.po ├── en │ └── LC_MESSAGES │ ├── django.mo │ └── django.po └── es └── LC_MESSAGES ├── django.mo └── django.po 6 directories, 6 files
Ésto buscará todos los .po de nuestro sistema y los generará a .mo para que puedan ser leídos por django. Cada vez que queramos añadir una cadena nueva a los ficheros .po para que estén disponibles se tendrán que compilar los .mo. Por ésto es bueno primero traducir toda la interfaz y después generar los ficheros de traducción, al revés es un engorro!
A continuación os dejo un pequeño TIP para cambiar el idioma de la interfaz a partir de una configuración de usuario, ya que por defecto coje los valores del navegador.
Para cambiar el idioma importaremos la librería translation
from django.utils import translation _profile = Profile.objects.get(pk=request.user.id) request.language = _profile.language.name request.lang = _profile.language.code translation.activate(request.lang)
Si lo que queremos es usar i18n en nuestros views_*.py
from django.utils.translation import ugettext_lazy as _ _status_translated = _("Status");
Y hasta aquí éste manual. Espero que te haya sido de ayuda :)