Interadictos Blog Programación y sistemas #symfony, I18N, UTF-8 y Dreamweaver
Programación y sistemas

#symfony, I18N, UTF-8 y Dreamweaver

Supongo 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%:

Supongo 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:

 

[codesyntax lang=»text» title=»Configuración del archivo settings.yml para internacionalización»]

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

[/codesyntax]

 

routing.yml

Modificamos este archivo para indicar el módulo que se mostrará como página de inicio (homepage):

 

[codesyntax lang=»text»]

# 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 }

[/codesyntax]

 

 

view.yml

Este archivo creo que no hacia falta modificarlo para la internacionalización, pero por si acaso:

[codesyntax lang=»text»]

  metas:
    language:     es

[/codesyntax]

 

indexSuccess.php del módulo

Añadimos el texto que vamos a probar:

[codesyntax lang=»php»]

// 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

[/codesyntax]

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:

[codesyntax lang=»php»]

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;
  }
}

[/codesyntax]

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:

[codesyntax lang=»text»]

<?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>

[/codesyntax]

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í;

[codesyntax lang=»php»]

// 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

[/codesyntax]

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.

Salir de la versión móvil