Damos un repaso a los distintos distintos métodos de implementación de páginas web multilenguaje, mostrando cómo implementar algunos de ellos. Si estás pensando en crear una web con contenido en varios idiomas… ¡tienes que leer esto!

Autor:

Intentando mejorar cada día en este mundo tan cambiante de la programación. Sígueme en Twitter o en GitHub. Actualmente estoy disponible para contratar.
Descarga Demostración

Introducción

Hoy en día, gracias a Internet, tenemos la capacidad de llegar a cualquier persona del mundo, desde al vecino del quinto hasta alguien perdido en algún lugar remoto de las antípodas. Esto es una enorme ventaja que no se puede desaprovechar cuando tienes un nicho de mercado global.

Si tu web ofrece un servicio o información que puede ser consumido por cualquier persona del mundo, tienes que cuidar muchos detalles para que el usuario final se sienta satisfecho y conforme. Se tiene que sentir como en casa.

Es importante presentar al usuario una web adaptada a su localización, tanto en idioma como en formatos (fecha, moneda, etc…) de forma que su experiencia en el sitio sea buena y así, mejorar la calidad de las visitas.

Sin embargo, tener una web en varios idiomas es algo complejo, tanto desde punto de vista técnico (que es la parte que ocuparemos en este artículo) como de mantenimiento. A continuación veremos los distintos métodos que puedes usar para convertir tu aplicación PHP en multilenguaje.

Formatos para las traducciones

La primera pregunta que te viene a la cabeza cuando comienzas con el diseño de una aplicación multilenguaje es: ¿cómo hago para abstraer los textos de las plantillas? ¿uso un array? ¿uso variables globales? ¿un fichero csv?.

Bien, a continuación os muestro un listado de los métodos más usados con sus ventajas e inconvenientes:

Array

Este es el formato más sencillo para los programadores, pero es ineficaz cuando tienes muchas cadenas de texto o muchos idiomas a traducir. Sin embargo puede ser una buena elección cuando se trata de un sitio pequeño con poco texto y en el cual es el programador quien se encarga de hacer las traducciones (si le pasas un array a alguna persona no técnica para traducir, seguramente se cargue algo).

Ficheros CSV

Este formato es cómodo cuando es el cliente (persona no técnica) el que se encarga de la traducción, pues es legible por cualquier editor de texto estándard. Sin embargo, se debe de tener cuidado con la codificación UTF8.

Gettext

Este es uno de los métodos más utilizados. gettext es la biblioteca GNU de internacionalización usada para crear programas de interfaz en múltiples lenguajes, y que en los últimos años ha dado el salto al mundo web.

Es un formato de traducción profesional, ya que no es legible como texto plano, sino que necesitas un programa de edición como POEdit, que evitará problemas de codificación y hará del proceso de traducción una experiencia más agradable. PHP incorpora funciones para trabajar con esta librería de forma nativa.

Ficheros Ini

Tiene las mismas características que los ficheros CSV, lo único que cambia es la forma de organizar los textos. Es un formato legible por el ser humano y adecuado para que el cliente edite los ficheros sin complicaciones. Se debe tener especial cuidado con la codificación UTF8.

TMX

Este formato será usado por clientes que tengan varios sistemas que usan una única fuente de traducción, o cuando la fuente de traducción necesita ser independiente del sistema (system-independent). TMX es un fichero basado en XML que parece encaminado a ser el próximo estándard en la industria.

Este tipo de ficheros son legibles por el ser humano, pero su procesamiento es más lento que el de ficheros gettext.

Usando gettext en PHP

De todos los formatos que he citado anteriormente, he elegido este para mostrar una implementación porque para mí es el más cómodo y profesional tanto para los traductores como para los programadores.

Primer paso: Instalar un editor y crear un catálogo

Como ya os he comentado antes, para este formato se necesita un editor capaz de manejar este tipo de ficheros. Yo os recomiendo POEdit, que es fácil de instalar y de aprender a manejar.

Antes de nada, tenéis que saber como funciona el programa, ya que, seguramente si no os lo dicen, no conseguiréis hacer nada con él. El concepto general de su funcionamiento sería el siguiente:

  • Le especificamos en que directorio(s) se encuentran los ficheros que contendrán los textos traducibles.
  • Le especificamos cual será lar marca que identificará que textos son traducibles. Normalmente el guión bajo (_) .
  • El programa se encarga de buscar en todos los ficheros, los textos traducibles y los añade a una lista para su traducción.

Vamos entonces a crear nuestro primer catálogo. Teniendo en cuenta que tenemos un fichero como el siguiente en /path/templates/template.php en donde path es el directorio del proyecto:

<html>
<body>
<h1><?=_("Hola  Mundo!")?></h1>
</body>
</html>

Aquí hay que destacar el uso de la funcion _ (guión bajo). Dicha función nos ofrece dos cosas: por un lado, es un alias de la función de PHP gettext, por lo tanto se encargará automáticamente de traducir ese texto una vez configurado. Y por otro lado ayudará al POEdit a encontrar las cadenas de texto traducibles.

Abrimos POEdit y vamos a Archivo > Nuevo catálogo y rellenamos información relativa al proyecto:

En la pestaña Carpetas debes indicar en que directorio se encuentran los ficheros con textos traducibles:

Y en la pestaña Palabras Clave seleccionamos cual va a ser el identificador de los textos traducibles. Como hemos dicho antes, lo más común es el guion bajo (_):

Una vez acaba la configuración, os pedirá en donde queréis guardar el fichero. Lo guardamos en /path/locale/en_US/LC_MESSAGES/app.po . En ese directorio, se creará tambien un fichero app.mo, que es el que nos interesa.

Segundo paso: Hacer la traducción

Una vez creado y guardado el catálogo, podemos comenzar la traducción. Como ves, el programa ha detectado los textos traducibles y te los sirve en bandeja para que los traduzcas. Más fácil imposible :)

Tercer paso: Traducir desde PHP

Como ya hemos dicho, en PHP exite la función gettext que nos permitirá trabajar con el fichero que acabamos de generar. Creamos el fichero /path/index.php

<?php
//Establecemos el  idioma a inglés
putenv('LC_ALL=en_US');
setlocale(LC_ALL, 'en_US.UTF8');

//Establecemos en que  directorio se encuentran las traducciones
bindtextdomain("app",  "./locale");

//Elegimos  el dominio (aka tabla o fichero)
textdomain("app");

// Incluyo el fichero  plantilla
require  'templates/template.php';

¡Así de sencillo! Ahora PHP ya se encarga de cargar los textos según el locale establecido. Pero…¿cómo lo encuentra si tenemos un esqueleto de carpetas bastante complejo? La respuesta es: tenemos ese esqueleto complejo porque es el que PHP espera tener. Analicemos directorio por directorio la ruta del fichero app.mo:

  • /path/locale: Con la función bindtextdomain le decimos a PHP que debe de buscar en ese directorio las traducciones.
  • /path/locale/en_US: Al establecer la configuración local a en_US con las funciones putenv y setlocale, PHP buscará este directorio.
  • /path/locale/en_US/LC_MESSAGES: este es un directorio en el que PHP busca por defecto.
  • /path/locale/en_US/LC_MESSAGES/app.mo: Cargará este fichero porque así se le ha especificado en la función textdomain.

Cuarto paso: Agregando nuevos textos

Si vuelves a agregar algun texto a la plantilla, no pasa nada, por defecto se mostrara sin traducir (que ya es algo mejor que nada) y luego simplemente tienes que abrir el catálogo con el editor y pinchar en el botón Actualizar catálogo

Y el programa ya te saca un listado de los nuevos textos que se han añadido:

Reflexion final

Como has visto, existen múltiples metodos para incorporar sistema multilenguaje en tu aplicación web. De ti, del usuario final, y del número de cadenas de texto a traducir depende la elección entre uno u otro, ya que cualquiera puede ser efectivo bajos determinadas condiciones.

Si te decantas por usar gettext, te darás cuenta que lo único que tienes que hacer es definir bien los catálogos y luego todo son ventajas, tanto para los desarrolladores como para los traductores.

Espero que os haya parecido interesante el artículo y que dejéis vuestra opinión sobre el tema…

¡Nos vemos en el próximo artículo!

¿Necesitas desarrollar un proyecto web o para móviles? ¡Estamos disponibles!

Visitar Cokidoo

Cokidoo, los creadores de Ontuts, desarrollamos proyectos tecnológicos centrados en redes sociales y aplicaciones web, aplicaciones móviles y consultoría web y bases de datos.

Somos jóvenes, inquietos, versátiles, apasionados por la innovación y enfocados en las nuevas tecnologías. Con Ontuts tratamos de compartir nuestro conocimiento adquirido en los distintos proyectos, ayudando a la comunidad y mostrando nuestra capacidad tecnológica.

Si necesitas un presupuesto sin compromiso, estamos disponibles, no dudes en contactar con nosotros.

Comentarios en esta publicación (21 comentarios)

¿Te ha gustado esta publicación? ¡Puedes compartir tu opinión con todos nosotros! Simplemente pincha aquí mismo.

Ya me habías chivado en la oficina de esta solución… impresionante la facilidad que ofrece al traductor.

Buen artículo como siempre ;)

Sergio N Hernandez

Hola Iván

Me ha gustado mucho tu articulo, nunca imagine que seria sencillo hacer una aplicacion multilenguaje con php…!!!

He encontrado muchos articulos que lo hacen con tablas, pero me resulta un poco anticuado y lleva un poco mas de trabajo.

Saludos

Alfredo

alguna recomendación con el javascript en el mismo ámbito ??

The_Maphius

Hola Ivan, soy novato en esto del PHP y estoy desarrollando una web para un projecto y e seguido el manual de como cambiar el idioma a mi web pero el problema me aparece cuando navego por mi web que el idioma se me pone al que esta por defecto y no se mantiene el que escojo.
Me gustaria que me dieras algun consejo de como mantener el idioma en el resto de paginas de mi web.

Hola The_Maphius,

Pues lo mejor que puedes hacer es separar el contenido en distintas URL, tienes varias opciones:

1. Crear distintos directorios virtuales: http://www.midominio.com/es/usuarios y http://www.midominio.com/en/users

2. Crear distintos dominios: http://www.midominio.es y http://www.midominio.com

3. Crear distintos subdominios: es.midominio.com y en.midominio.com

Un saludo!

@The_Maphius: Usa Sesiones , ten un archivo ejemplo: “es, en” en ellos guardas las variables que imprimes en tu web:: ejemplo: $texto = “Hola” (carpeta “es”), $texto = “hello”(carpeta “en”) y mediante sesiones cargas la carpeta de variables en “en” o en “es” cosa que siempre se mantendrán las webs con el mismo idioma así des retroceder.
una web d 2 idiomas q programé fue esta, para q veas masomenos como qda:
http://www.textilsp.com

The_Maphius

Hola Jp++, no se si te habran llegado pero deje unos mensages en el foro y al parecer no han aparecido, primero de todo mersi x la info me estado mirando tu web y es como quiero que sea la mia con lo del tema del idioma lo que al ser nuevo en esto del php no me keda muy claro como hacer,sino te importa me gustaria k me pasases un ejemplo de como lo hicistes tu para pasar de una pagina a otra conservando el idioma.
Gracias de antemano.

Alguna solucion para poder tratar traducciones que estan contenidas en variables php?
De esta forma estamos traduciendo contenido estatico, pero podriamos traducir tambien el dinamico?

Hola Francisco,

Puedes hacer una especie de truco con el GetText, puede que te sirva y te convenza, o puede que te parezca una chapuza…

Tu puedes hacer eso perfectamente en tu código: _($variable)

Si el contenido de $variable lo tienes por casualidad dentro de la base de datos de los textos, se te traducirá perfectamente. Ahora bien, ¿cómo puedes añadir textos a la base de datos que no están dentro de ningún contenido estático? Pues simplemente creas un fichero y vas metiendo en el todos los textos dinámicos que puedan aparecer.

Por ejemplo, imagina que traes de la base de datos un texto que representa a una categoría, y sabes que siempre vas a tener cuatro categorías: Todos, Abiertos, Cerrados, Cancelados. Pues creas un fichero ‘dummy’ con el siguiente contenido:
_(‘Todos’);
_(‘Abiertos’);
_(‘Cerrados’);
_(‘Cancelados’);
La proxima vez que actualices la base de datos de textos, te aparecerán las 4 categorías y se traducirán, estén en estático o en variables.

¡Un saludo!

Gracias Ivan, me parece buena opcion.
He estado barajando el usar la API de google translator solo para los contenidos dinamicos. La solucion es muy buena, ya que lo hace perfectamente. El problema? google lo tiene en estado DEPRECATED, y puede que dure infinito, o que tenga los dias contados. Supongo que mientras no se abuse ira bien.
Igualmente te agradezco la contestacion ya que me sirve bastante para lo que quiero.
Un saludo :D

Buenas de nuevo Francisco,

Yo tambien he estado mirando la API de Google hace poco, pero como bien dices está obsoleta. He leído en algún blog de Google que la van a poner de pago.

Un saludo

Pablo

¡Buenas!

Estaba probando a implementar gettext con tu tutorial en un jueguecillo que estoy haciendo, pero me mostraba el texto original igualmente.

Tras un rato toqueteando las rutas, buscando en google problemas similares y todo eso, no he llegado a nada. De hecho, también he descargado tu proyecto, lo he descomprimido tal cual en htdocs, y seguía sin funcionar. ¿Tengo que activar algún módulo extra o algo?

Ante todo, muchas gracias por la guía, se entiende de maravilla, y se siente un calor especial cuando ves a más gente usando Ubuntu XD

Hola Pablo,

¿Tu en el Poedit llegas a obtener los textos de la aplicación? Normalmente es dónde más se atasca la gente, una vez hecho eso no suele haber problema.

Por otro lado, no conozco que haya que tener nada especial, si la funcion “_()” no te da error es porque tienes la librería gettext instalada y por lo tanto debería funcionar.

Siento no ser de más ayuda

Pablo

Extraña movida.

Subí exactamente el mismo proyecto a 000webhost, y lo ejecuté simultáneamente tanto en localhost (XAMPP) como en el hosting. Y funcionó.

http://img833.imageshack.us/img833/8443/lolazor.png

Tengo con unos amigos una coña acerca de una teoría llamada “Asentamiento de bytes”. Si algo no va, si no se enciende el ordenador, si se ha roto algo, deja que los bytes se asienten, que empezará a funcionar solo. Y es que últimamente veo tantos casos que creo que voy a escribir una tesis…

Alex

Hola Ivan, yo también te quiero molestar :$, bueno mi pregunta es como manejo cuando quiero traducir mi web en 3 idiomas como hago los archivos .po bueno los creo pero como haglo el enlace para saber de que idioma a que idioma estoy traduciendo en php por ejemplo.

De antemano gracias por la ayuda

Buenos días, felicidades por el artículo, es lo más simple y lo más fácilmente entendible que he visto por ahí, gracias a vosotros creo que puedo empezar a traducir mi web, no obstante, tengo un problema y es que POedit no me reconoce los ficheros php que quiero traducir. No me actualiza bien a pesar de meter bien el directorio.
¿Sabéis a qué puede deberse?¿le ha pasado a más gente?
Puede tener que ver que lo haga desde win en lugar de linux?
Un saludo y gracias por vuestra labor

Arrate

Hola.

Sigo las instrucciones y me funciona perfectamente en mi servidor local pero cuando los subo al remote server no funciona. He subido vuestro ejemplo y funciona.

¿Sabeís que puede ocurrir? yo creo que tiene que haber algún problema con el archivo .mo que genero.

Luz Arevalo

Hola todos,

tengo una pregunta estoy trabajando con la version 5.4 del CRM Vtiger, yo deseo enviar los correos y que en cuerpo del correo yo pueda incluir el saludo es decir “respetado senor” o algo asi. Este saludo esta en la tabla de mis clientes pero esta archivado en ingles asi que cuando logro que se vea en el Email. pues mis clientes lo reciben en Ingles. ustedes me pueden indicar como logro la traduccion del contenido de esa variable.

mil gracias

Mauro

¿como podría implementar este método para traducir contenido sacado de una base de datos? Por ejemplo una publicación en un blog