Para realizar una página web multi-idioma necesitamos solucionar varios problemas con la traducción de los textos en diferentes idiomas.
Para realizar una página web multi-idioma necesitamos solucionar varios problemas o casuísticas. Vamos a numerarlas rápidamente y posteriormente daremos una posible solución para cada una.
En líneas generales, la solución pasa por tener guardados en variables todos los textos que se van a mostrar en la página. Podemos utilizar variables tal cual o bien generar un array con todos los textos a traducir, lo que puede mejorar la organización del código.
Veamos las explicaciones de los tres casos señalados anteriormente.
1) Podemos tener textos planos que traducir, es decir, textos que simplemente debemos colocarlos en un idioma u otro, dependiendo de la preferencia del usuario.
Por ejemplo, tenemos que poner escribir palabra "nombre" en la página. En español escribiremos "nombre", pero cuando se visite el sitio en inglés, escribiríamos "name".
Esto lo estamos solucionando con un fichero de texto, en el que tenemos como variables todas las palabras o frases planas que se necesitan escribir en la página, en varios idiomas. Así tenemos un fichero con las palabras y frases en español, otro con las del idioma inglés y, por ejemplo, otro con las de portugués.
Las variables que estamos utilizando son del estilo $idioma_loquesea. Por ejemplo, en el fichero en español podemos tener varias palabras y frases como estas:
$idioma_nombre = "nombre";
$idioma_direccion = "dirección";
$idioma_error_usuario = "Hemos detectado un error con el usuario";
En el idioma inglés tendríamos un fichero parecido a este: (perdonar si mis traducciones no son del todo correctas)
$idioma_nombre = "name";
$idioma_direccion = "address";
$idioma_error_usuario = "We have detected an user error";
En las páginas multi-idioma, detectaríamos el idioma que ha seleccionado el usuario, para incluir un fichero de idioma u otro.
Luego, al mostrar un texto, podríamos sacar algo como esto:
echo $idioma_nombre . ": pepe";
echo $idioma_direccion . ": C/ corona, 2";
Dependiendo del fichero de idioma que se haya incluido tendremos un resultado distinto. En español saldría:
nombre: pepe
dirección: C/ corona, 2
Si hubiéramos incluido el fichero de idioma inglés, obtendríamos como salida
name: pepe
address: C/ corona, 2
2) Podemos tener otro caso de elementos a traducir más complejo. Supongamos que tenemos una tabla de países. Los países se llaman de manera distinta en cada idioma, así que de alguna manera tenemos que almacenar el nombre del país para muchos idiomas distintos.
Esto se puede hacer de varias maneras. Por ejemplo, podríamos tener una tabla con los identificadores de los países y la traducción para cada idioma. Luego, en la página dependiendo del idioma, tendríamos que mostrar un texto u otro para el país, seleccionando la traducción que necesitamos para el país.
Por ejemplo, podríamos tener la tabla pais, de esta manera:
id_pais - nombre_pais_es - nombre_pais_en
1 - España - Spain
2 - Italia - Italy
3 - Francia - France
Luego, al recuperar los nombres de los países, podríamos hacer algo como esto:
if ($lenguaje_seleccionado = "ES"){
$ssql = "select id_pais, nombre_pais_es as 'nom_pais' from pais";
}else{
$ssql = "select id_pais, nombre_pais_en as 'nom_pais' from pais";
}
Luego, recuperaríamos los datos de la tabla y en el campo 'nom_pais' tendremos la traducción que necesitamos.
Pero esto no nos gusta, porque no nos estamos abstrayendo del idioma del usuario para mostrar el nombre del país. Es decir, en el código de la aplicación tenemos que hacer cosas distintas para cada idioma. Lo mejor sería programar la página igual, sin tener que preguntar en ningún momento el idioma en el que estamos trabajando, así no habrá que tocar el código nunca para incorporar nuevos idiomas, ni estamos mezclando la lógica de la aplicación con la lógica de la gestión del idioma.
Una solución para mejorar esto es utilizar un fichero de texto para los nombres de los países y tener un fichero de texto para cada idioma, de manera similar a lo que habíamos comentado para el caso anterior.
Dentro de este fichero, tendremos los nombres de los países, en un archivo independiente para cada idioma. Los nombres los podemos meter en un array para facilitar su gestión, con los índices iguales al identificador utilizado en la tabla país.
Para el idioma español tendríamos:
$idioma_nombre_pais[1] = "España";
$idioma_nombre_pais[2] = "Italia";
$idioma_nombre_pais[3] = "Francia";
Para el idioma inglés, tendríamos:
$idioma_nombre_pais[1] = "Spain";
$idioma_nombre_pais[2] = "Italy";
$idioma_nombre_pais[3] = "France";
Luego, al seleccionar los distintos países de la base de datos, la sentencia SQL será la misma:
$ssql = "select id_pais from pais";
Al mostrar los nombres de países, tan sólo tenemos que acceder al array $idioma_nombre_pais, con el índice del país que se desea mostrar. Es decir, el código será el mismo, aunque el resultado al visualizar el nombre de país dependerá del archivo de idioma que hayamos cargado (en español o inglés). Por ejemplo, si quisiéramos mostrar un elemento de formulario <select> con los distintos países el código sería:
echo "<select name='id_pais'>";
$ssql = "select id_pais from pais";
$rs = mysql_query($ssq);
while ($fila = mysql_fetch_object($rs)){
echo "<option value='" . $fila->id_pais . "'>";
echo $idioma_nombre_pais[$fila->id_pais];
echo "</option>";
}
echo "</select>";
3) El último caso que vamos a ver en las traducciones es una mezcla entre textos planos y valores de variables. Por ejemplo, pensemos en una frase como esta:
Tienes X documentos subidos, Y abiertos
Donde X es el valor de una variable numérica, al igual que Y. Lógicamente, en lugar de la X o la Y, lo que queremos ver es el valor numérico que tengan esas variables.
Para implementar cómodamente esta parte del sistema multi-idioma, podemos utilizar la función printf(), que es parecida a echo, pero aparte de la cadena a mostrar, permite indicar otros parámetros con valores que se que se sustituirán en la cadena, antes de mostrarla en la página. Veamos con un ejemplo esto.
La cadena en español que queremos mostrar es:
$idioma_documentos_abiertos = "tienes %1u documentos subidos, %2u abiertos";
En inglés, este mismo mensaje quedaría:
$idioma_documentos_abiertos = "You have upload %1u documents, %2u open";
Con "%1u" en la cadena hemos especificado un parámetro y con "%2u" hemos especificado otro parámetro. Ambos se debe sustituir por un valor que también enviaremos a printf(). Del parámetro "%1u", la parte del "%1" hace referencia al primer parámetro y la "u" dice que es numérico, en base 10, sin decimales.
En la llamada a printf() debemos especificar la cadena a mostrar y los parámetros que se deben sustituir en la cadena, en nuestro ejemplo 2.
printf($idioma_documentos_abiertos, 6, 4);
Esto tendrá como salida, para la frase en español:
tienes 6 documentos subidos, 4 abiertos
- Traducción de textos planos
- Traducción de textos que están insertados en una base de datos
- Traducción de textos mezclados con valores de variables
En líneas generales, la solución pasa por tener guardados en variables todos los textos que se van a mostrar en la página. Podemos utilizar variables tal cual o bien generar un array con todos los textos a traducir, lo que puede mejorar la organización del código.
Veamos las explicaciones de los tres casos señalados anteriormente.
1) Podemos tener textos planos que traducir, es decir, textos que simplemente debemos colocarlos en un idioma u otro, dependiendo de la preferencia del usuario.
Por ejemplo, tenemos que poner escribir palabra "nombre" en la página. En español escribiremos "nombre", pero cuando se visite el sitio en inglés, escribiríamos "name".
Esto lo estamos solucionando con un fichero de texto, en el que tenemos como variables todas las palabras o frases planas que se necesitan escribir en la página, en varios idiomas. Así tenemos un fichero con las palabras y frases en español, otro con las del idioma inglés y, por ejemplo, otro con las de portugués.
Las variables que estamos utilizando son del estilo $idioma_loquesea. Por ejemplo, en el fichero en español podemos tener varias palabras y frases como estas:
$idioma_nombre = "nombre";
$idioma_direccion = "dirección";
$idioma_error_usuario = "Hemos detectado un error con el usuario";
En el idioma inglés tendríamos un fichero parecido a este: (perdonar si mis traducciones no son del todo correctas)
$idioma_nombre = "name";
$idioma_direccion = "address";
$idioma_error_usuario = "We have detected an user error";
En las páginas multi-idioma, detectaríamos el idioma que ha seleccionado el usuario, para incluir un fichero de idioma u otro.
Luego, al mostrar un texto, podríamos sacar algo como esto:
echo $idioma_nombre . ": pepe";
echo $idioma_direccion . ": C/ corona, 2";
Dependiendo del fichero de idioma que se haya incluido tendremos un resultado distinto. En español saldría:
nombre: pepe
dirección: C/ corona, 2
Si hubiéramos incluido el fichero de idioma inglés, obtendríamos como salida
name: pepe
address: C/ corona, 2
2) Podemos tener otro caso de elementos a traducir más complejo. Supongamos que tenemos una tabla de países. Los países se llaman de manera distinta en cada idioma, así que de alguna manera tenemos que almacenar el nombre del país para muchos idiomas distintos.
Esto se puede hacer de varias maneras. Por ejemplo, podríamos tener una tabla con los identificadores de los países y la traducción para cada idioma. Luego, en la página dependiendo del idioma, tendríamos que mostrar un texto u otro para el país, seleccionando la traducción que necesitamos para el país.
Por ejemplo, podríamos tener la tabla pais, de esta manera:
id_pais - nombre_pais_es - nombre_pais_en
1 - España - Spain
2 - Italia - Italy
3 - Francia - France
Luego, al recuperar los nombres de los países, podríamos hacer algo como esto:
if ($lenguaje_seleccionado = "ES"){
$ssql = "select id_pais, nombre_pais_es as 'nom_pais' from pais";
}else{
$ssql = "select id_pais, nombre_pais_en as 'nom_pais' from pais";
}
Luego, recuperaríamos los datos de la tabla y en el campo 'nom_pais' tendremos la traducción que necesitamos.
Pero esto no nos gusta, porque no nos estamos abstrayendo del idioma del usuario para mostrar el nombre del país. Es decir, en el código de la aplicación tenemos que hacer cosas distintas para cada idioma. Lo mejor sería programar la página igual, sin tener que preguntar en ningún momento el idioma en el que estamos trabajando, así no habrá que tocar el código nunca para incorporar nuevos idiomas, ni estamos mezclando la lógica de la aplicación con la lógica de la gestión del idioma.
Una solución para mejorar esto es utilizar un fichero de texto para los nombres de los países y tener un fichero de texto para cada idioma, de manera similar a lo que habíamos comentado para el caso anterior.
Dentro de este fichero, tendremos los nombres de los países, en un archivo independiente para cada idioma. Los nombres los podemos meter en un array para facilitar su gestión, con los índices iguales al identificador utilizado en la tabla país.
Para el idioma español tendríamos:
$idioma_nombre_pais[1] = "España";
$idioma_nombre_pais[2] = "Italia";
$idioma_nombre_pais[3] = "Francia";
Para el idioma inglés, tendríamos:
$idioma_nombre_pais[1] = "Spain";
$idioma_nombre_pais[2] = "Italy";
$idioma_nombre_pais[3] = "France";
Luego, al seleccionar los distintos países de la base de datos, la sentencia SQL será la misma:
$ssql = "select id_pais from pais";
Al mostrar los nombres de países, tan sólo tenemos que acceder al array $idioma_nombre_pais, con el índice del país que se desea mostrar. Es decir, el código será el mismo, aunque el resultado al visualizar el nombre de país dependerá del archivo de idioma que hayamos cargado (en español o inglés). Por ejemplo, si quisiéramos mostrar un elemento de formulario <select> con los distintos países el código sería:
echo "<select name='id_pais'>";
$ssql = "select id_pais from pais";
$rs = mysql_query($ssq);
while ($fila = mysql_fetch_object($rs)){
echo "<option value='" . $fila->id_pais . "'>";
echo $idioma_nombre_pais[$fila->id_pais];
echo "</option>";
}
echo "</select>";
3) El último caso que vamos a ver en las traducciones es una mezcla entre textos planos y valores de variables. Por ejemplo, pensemos en una frase como esta:
Tienes X documentos subidos, Y abiertos
Donde X es el valor de una variable numérica, al igual que Y. Lógicamente, en lugar de la X o la Y, lo que queremos ver es el valor numérico que tengan esas variables.
Para implementar cómodamente esta parte del sistema multi-idioma, podemos utilizar la función printf(), que es parecida a echo, pero aparte de la cadena a mostrar, permite indicar otros parámetros con valores que se que se sustituirán en la cadena, antes de mostrarla en la página. Veamos con un ejemplo esto.
La cadena en español que queremos mostrar es:
$idioma_documentos_abiertos = "tienes %1u documentos subidos, %2u abiertos";
En inglés, este mismo mensaje quedaría:
$idioma_documentos_abiertos = "You have upload %1u documents, %2u open";
Con "%1u" en la cadena hemos especificado un parámetro y con "%2u" hemos especificado otro parámetro. Ambos se debe sustituir por un valor que también enviaremos a printf(). Del parámetro "%1u", la parte del "%1" hace referencia al primer parámetro y la "u" dice que es numérico, en base 10, sin decimales.
En la llamada a printf() debemos especificar la cadena a mostrar y los parámetros que se deben sustituir en la cadena, en nuestro ejemplo 2.
printf($idioma_documentos_abiertos, 6, 4);
Esto tendrá como salida, para la frase en español:
tienes 6 documentos subidos, 4 abiertos
Miguel Angel Alvarez
Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...