Creación de proyecto y de la aplicación web
Vamos a empezar por el principio y lo primero siempre es crear el proyecto y ver que funciona correctamente. Como siempre lo hacéis en el entorno de desarrollo que mas os guste python venv, docker, vagrant ... este ultimo es mi preferido para hacer las pruebas de los artículos.Pero como no quiero repetir siempre lo mismo, porque para todos los proyectos la configuración de paquetes y módulos requeridos es la misma he creado un artículo donde muestro como crear un proyecto y hacer que funciones con el servidor local de django o con Apache2
Como configurar Django con Apache2 con mod_wsgi en Linux
Cuando esto funcione y muestre la página de bienvenida de Django pasamos al punto 2 para empezar la configuración del proyecto / aplicación web.
Configurar el proyecto para que acepte multiples idiomas
Para dar soporte para multiples idiomas tenemos que añadir la siguiente configuración en el fichero settings.py
# al principio de todo en la seccion de imports
import os
# Idioma por defecto
LANGUAGE_CODE = 'en-us'
# Zona horaria
TIME_ZONE = 'UTC'
# Activar la traducción
USE_I18N = True
# Usar zonas horarias locales
USE_L10N = True
# Idiomas disponibles
LANGUAGES = [
('en', 'English'),
('es', 'Spanish'),
# Puedes agregar más idiomas aquí
]
# Rutas para los archivos de traducción
LOCALE_PATHS = [
os.path.join(BASE_DIR, 'locale'),
]
Fijaros porque LANGUAGE_CODE, TIME_ZONE, USE_I18N ya vienen definidas en el archivo settings.py.
Hay que añadir también el middleware del lenguaje en el fichero settings.py.
MIDDLEWARE = [
# ...
'django.middleware.locale.LocaleMiddleware',
# ...
]
Configurar aplicación y mostrar una vista
Vamos a configurar la aplicación web para que muestre un texto en el navegador, para esto tenemos que definir una ruta y crear un template html para mostrar el texto en el navegador.Lo primero que tenemos que hacer es modificar el fichero de urls.py del proyecto principal y decir que tenemos un segundo fichero urls que pertenece a a la aplicación web incluyendo esto:
path('', include('web.urls'))
Y el fichero urls.py del proyecto principal quedaría así:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
# incluimos el fichero de urls de la aplicación web
path('', include('web.urls'))
]
Ahora en la aplicación web creamos un fichero llamado urls.py y ponemos dentro lo siguiente
from django.urls import path
from .views import index
urlpatterns = [
path('', index, name="index"),
]
Definidas las urls, en este caso solo una de ejemplo, creamos un directorio templates y dentro un fichero html, index.html y dentro del index ponemos un texto por ejemplo Bienvenidos al multi idioma con etiquetas h1.
Y ahora nos queda modificar la vista para que muestre el index.html, dentro del fichero views.py eliminar lo que hay y poner el siguiente código
from django.shortcuts import render
from django.core.serializers import serialize
from django.http import HttpResponse, JsonResponse
def index(request):
return render(request, 'index.html', { })
Y ahora lo probamos ejecutando el servidor de Django desde el terminal
python manage.py runserver
Crear los ficheros de idiomas
Ya tenemos la configuración del idioma en el fichero settings.py creada la primera página del web donde tendremos que cambiar los texto y poner las traducciones de la siguiente manera:
<h1>{% trans "welcome" %}</h1>
<p class="fs-3">{% trans "welcome_parrafo" %}</p>
{% load i18n %}
Ahora vamos a crear los ficheros de traducción, lo primero que haremos es crear un directorio donde irán estos ficheros de traducciones y por convenio se llama locale pero esto esta definido en el fichero settings.py y creo que se puede cambiar el nombre pero no lo he probado, y crearlo dentro de la aplicación web
cd web
mkdir locale
django-admin makemessages -l en -l es
Y esto creará los ficheros donde pondremos las traducciones. Si después añadimos mas idiomas con volver a ejecutar este comando con el idioma nuevo es suficiente.Estructura del fichero de idiomas
Un fichero de idioma de Django tiene la siguiente estructura:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR , YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-01-28 07:10+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: templates/index.html:19
msgid "welcome"
msgstr ""
#: templates/index.html:20
msgid "welcome_parrafo"
msgstr ""
La primera parte es un poco explicación y datos de configuración del fichero y la traducción empieza en:
#: templates/index.html:19
msgid "welcome"
msgstr "Bienvenidos al multi idioma"
- La primera linea es donde va esa traducción (opcional).
- La segunda linea es el indice msgid es el id que ponemos en el html {% trans "welcome" %}
- La tercera linea es la traducción msgstr y es lo que varia en cada idioma
Y para que todo funcione correctamente se tienen que compilar los ficheros de idiomas con el siguiente comando, transformado los ficheros .po en ficheros .mo, en realidad crea unos nuevos donde pone las traducciones en formato que Django los lea.
django-admin compilemessages
Cada vez que modifiquemos los ficheros .po de las traducciones tenemos que ejecuta el comando compilemessages para regenerar los fichero .moMenú de navegación por idioma
Una vez configurado el idioma y los ficheros de idioma vamos a crear un menú para cambiar de idioma. A nuestra página index.html añadimos tres enlaces a los tres idiomas que tenemos configurados.
<a class="fs-4" href="/en/" role="button">{% trans "English" %}</a> |
<a class="fs-4" href="/es/" role="button">{% trans "Spanish" %}</a> |
<a class="fs-4" href="/fr/" role="button">{% trans "French" %}</a>
from django.contrib import admin
from django.urls import path, include
from django.conf.urls.i18n import i18n_patterns
urlpatterns = [
path('admin/', admin.site.urls),
]
urlpatterns += i18n_patterns(
# incluimos el fichero de urls de la aplicación web
path('', include('web.urls'))
)
He añadido i18n_patterns delante de las rutas que requieren idioma.
Ahora si probamos el web podremos navegar entre los diferentes idiomas
Por último comentar que esta configuración para soporta multiples lenguajes utiliza el idioma del navegador por defecto así que la página que no tengáis enlazada con el idioma utilizará el del navegador porque hace caso omiso de la variable LANGUAGE_CODE, para poder utilizar esta variable y setear el idioma en tiempo de ejecución hay que crearse un middleware que realice esta funcion y sustituir el que trae por defecto Django ... pero esto ya lo veremos mas adelante :-)
Dejo el código del proyecto en github: https://github.com/depruebas/django-soporte-idiomas
Y esto es todo, feliz programming
Saludos
Alex.