Entradas etiquetadas con internacionalización
#symfony, I18N, UTF-8 y Dreamweaver
0Supongo que ya sabrás de lo que voy a hablar, sí, codificación de caracteres y el jodío de Dreamweaver. Te cuento:
Estoy haciendo algunas pruebas con Symfony y su sistema de internacionalización ( I18N ), y para ello he hecho que el charset que muestre la plantilla sea utf-8 (además de las tablas de la BD y las conexiones desde y hacía la BD), lo curioso es que cuando he ido a verlo en el navegador el resultado me aparecía con chinos (unos cuadrados (aunque pueden ser otros símbolos) que sustituyen a las letras con tilde), total que me he tirado todo el día dándole vueltas al tema, y el problema lo tenía en Dreamweaver que, por defecto, guarda los archivos en «Europeo occidental» y no en utf-8.
Te explico todo lo que he modificado en el proyecto de Symfony, por si te pasa algo parecido puedas comparar. Con esta configuración que te voy a mostrar el sistema de internacionalización de Symfony funciona al 100%:
Antes de nada te informo que esto está pensado para Symfony 1.4, versiones superiores o inferiores pueden necesitar una configuración distinta. Cuando hablo de Dreamweaver me refiero a la versión CS3, aunque muy probablemente algo parecido haya en versiones superiores.
settings.yml
Doy por hecho que ya has creado el proyecto, al menos una aplicación y un módulo con el que hacer pruebas. Nos vamos al archivo settings.yml de la app y añadimos:
- all:
- .settings:
-
- # Indicamos la cultura por defecto
- # Aquí poned la que os interese
- default_culture: es_ES
-
- # Indicamos la codificación de caracteres
- charset: utf-8
-
- # Esto lo dejo a tu elección
- # Puedes escribir esta línea para que el helper I18N esté
- # en todas las plantillas de forma global
- # Lo bueno de usar esta opción es que puedes añadir
- # más helpers:
- # standard_helpers: [I18N,text, etc]
- standard_helpers: [I18N]
-
- # O puedes escribir esta otra línea, pero
- # en cada una de las plantillas tendrás que incluir
- # al prinicipio <?php use_helper('I18N') ?>
- # la decisión es tuya
- i18n: true
routing.yml
Modificamos este archivo para indicar el módulo que se mostrará como página de inicio (homepage):
- # Esto es lo que está por defecto
- homepage:
- url: /
- param: { module: default, action: index }
-
- # Lo único que cambio es el nombre del módulo, que en mi caso es 'login'
- homepage:
- url: /
- param: { module: login, action: index }
view.yml
Este archivo creo que no hacia falta modificarlo para la internacionalización, pero por si acaso:
- metas:
- language: es
indexSuccess.php del módulo
Añadimos el texto que vamos a probar:
- // No voy a poner todo el código que tengo en mi plantilla
- // así que pongo solo un ejemplo
-
- <?php echo __('Hola Mundo!') ?>
-
- // Esto te mostrará el texto en español
Bien, como le hemos dado el valor «es_ES» a «default_culture«, Symfony no mostrará ninguna traducción sino el valor que le hemos indicado en la plantilla. Para hacer una prueba en condiciones vamos a modificar la cultura de un usuario a «en_EN«, esto mantendrá la cultura de todo el proyecto como «es_ES«.
actions.class.php del módulo
En la acción Index escribimos lo siguiente:
- class loginActions extends sfActions
- {
- /**
- * Executes index action
- *
- * @param sfRequest $request A request object
- */
- public function executeIndex(sfWebRequest $request)
- {
-
- // Esta línea cambiará la cultura SÓLO para el usuario
- $this -> getUser() -> setCulture('en_EN');
-
- return sfView::SUCCESS;
- }
- }
Obviamente nos falta crear el archivo que le indicará a Symfony el texto que debe utilizar para su sustitución. A ello voy:
english.en.xml
Este archivo se guarda en la carpeta «i18n» de la app, aunque también puedes crear la carpeta dentro del módulo y guardar el archivo allí. Este archivo tiene un formato especial que se debe mantener:
- <?xml version="1.0" encoding="utf-8"?>
- <xliff version="1.0">
- <file orginal="global" source-language="en_EN" datatype="plaintext">
- <body>
- <trans-unit id="1">
- <source>Hola Mundo!</source>
- <target>Hello World!</target>
- </trans-unit>
- <trans-unit id="2">
- <source>soy un texto</source>
- <target>I'm a text</target>
- </trans-unit>
- <trans-unit id="3">
- <source>Adiós</source>
- <target>Bye</target>
- </trans-unit>
- </body>
- </file>
- </xliff>
Cosas importantes respecto de este archivo:
- Le puedes poner cualquier nombre pero debe acabar en *.culture.xml, por ejemplo: login.en.xml, registro.en.xml, administracion.fr.xml, comentario.it.xml.
- También se puede poner la cultura completa, es decir, en vez de solo *.en.xml puedes nombrarlo como *.en_EN.xml.
- El parámetro «source-language» siempre debe indicar la cultura que se va a traducir, en este caso es el ingles (en_EN).
- Cada texto a traducir está dentro de la etiqueta <trans-unit>, que tiene el atributo id, pues bien, cada frase a traducir debe aumentar el id ( 1,2,3,4,5….500 etc)
- No es necesario que todas las frases estén en un solo archivo, puede haber varios archivos con textos diferentes, por ejemplo, para el menú, la cabecera, el pie de página, etc.,. Importante: aunque sean archivos para idiomas diferentes el nombre del archivo siempre debe ser el mismo, variando, eso sí, la cultura.
Una vez guardado el archivo volvemos al indexSuccess.php y lo modificamos para que quede tal que así;
- // No voy a poner todo el código que tengo en mi plantilla
- // así que pongo solo un ejemplo
-
- <?php echo __('Hola Mundo!', null, 'login') ?>
-
- // Ahora mostrará el texto que corresponda con la cultura del usuario
- // Además lo buscará en un archivo concreto en este caso login.en.xml
Y así se internacionaliza un proyecto Symfony. Ahora el problemita de Dreamweaver:
El bicho, (por llamarlo de alguna manera) tiene una opción para abrir archivos que no indiquen su codificación. Normalmente está en «Europeo occidental» y debería estar en «Unicode (utf-8)«. Para cambiarlo accedemos al menú «Edición -> Preferencias…» y en «Nuevo documento» busca un desplegable que ponga «Codificación pred.«; ahí elige «Unicode (utf-8)«, activa la casilla que dice «Utilizar al abarir archivos existentes que no indiquen su codificación» y en el desplegable de abajo (Formulario de normas Unicode) selecciona «C (descomposición de compatibilidad seguida de composición canónica)«. Pulsa aceptar y prueba el en navegador.
Tal vez tengas que limpiar la cache de Symfony para ello solo tienes que escribir en la consola (que debe apuntar a la carpeta donde tienes el proyecto) symfony cc o php symfony cc.
Si sigue fallando, abre el archivo indexSuccess.php del módulo con el bloc de notas, y sin modificar nada, vete a Archivo -> Guardar como… , ahí podrás elegir la codificación, en nuestro caso, utf-8, y para evitar que se guarde como un archivo .txt elige «Todos los archivos» y así se guardará en php. Vuelve a limpiar la caché y vuelve a probar, ahora sí te debería funcionar bien.