Symfony 2.1, el libro oficial

15.2. Traducción básica

La traducción de texto se realiza a través del servicio translator. Para traducir un bloque de texto (también llamado mensaje), se utiliza el método trans. Supongamos, por ejemplo, que estás traduciendo un mensaje dentro de un controlador:

// ...
use Symfony\Component\HttpFoundation\Response;

public function indexAction()
{
    $translated = $this->get('translator')->trans('Symfony2 is great');

    return new Response($translated);
}

Al ejecutar este código, Symfony2 trata de traducir el mensaje Symfony2 is great, basándose en el valor del locale del usuario. Para que la traducción se produzca, debes indicar a Symfony2 cómo traducir el texto mediante un "recurso de traducción", que es una colección de traducciones para un determinado idioma. Este diccionario de traducciones se puede crear en diferentes formatos, pero el formato estándar XLIFF es el recomendado:

<!-- messages.fr.xliff -->
<?xml version="1.0"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
    <file source-language="en" datatype="plaintext" original="file.ext">
            <body>
            <trans-unit id="1">
                <source>Symfony2 is great</source>
                <target>J'aime Symfony2</target>
            </trans-unit>
        </body>
    </file>
</xliff>
// messages.fr.php
return array(
    'Symfony2 is great' => 'J\'aime Symfony2',
);
# messages.fr.yml
Symfony2 is great: "J'aime Symfony2"

Ahora, si el idioma del usuario es el francés (su locale es por ejemplo fr_FR o fr_BE), el mensaje será traducido a J'aime Symfony2.

15.2.1. El proceso de traducción

Symfony2 utiliza un proceso bastante sencillo para traducir los mensajes:

  • Determina el locale del usuario, que se encuentra almacenado en la petición (o almacenado como _locale en la sesión).
  • Carga el catálogo de mensajes traducidos para ese locale (por ejemplo, fr_FR). También se cargan los mensajes del locale por defecto. El resultado es un gran diccionario de traducciones.
  • Si se encuentra el mensaje en el catálogo de traducciones, se devuelve la traducción. En caso contrario, el traductor devuelve el mensaje original.

Cuando se usa el método trans(), Symfony2 busca la cadena de texto exacta dentro del catálogo de mensajes y si existe, la devuelve.

15.2.2. Mensajes con variables

Resulta habitual que los mensajes a traducir contengan en su interior valores variables:

// ...
use Symfony\Component\HttpFoundation\Response;

public function indexAction($name)
{
    $translated = $this->get('translator')->trans('Hello '.$name);

    return new Response($translated);
}

Como el traductor siempre busca la cadena exacta, no es posible traducir este mensaje porque la variable $name puede tomar cualquier valor. En vez de escribir una traducción para cada posible valor de la variable $name, se puede reemplazar la variable por algo denominado placeholder o "marcador de posición":

// ...
use Symfony\Component\HttpFoundation\Response;

public function indexAction($name)
{
    $translated = $this->get('translator')->trans(
        'Hello %name%',
        array('%name%' => $name)
    );

    return new Response($translated);
}

Symfony2 ahora buscará una traducción para la cadena Hello %name% y después reemplazará los marcadores de posición por sus valores. La traducción de esta cadena se define igual que antes:

<!-- messages.fr.xliff -->
<?xml version="1.0"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
    <file source-language="en" datatype="plaintext" original="file.ext">
            <body>
            <trans-unit id="1">
                <source>Hello %name%</source>
                <target>Bonjour %name%</target>
            </trans-unit>
        </body>
    </file>
</xliff>
// messages.fr.php
return array(
    'Hello %name%' => 'Bonjour %name%',
);
# messages.fr.yml
'Hello %name%': Bonjour %name%

Nota Los marcadores de posición pueden utilizar cualquier formato, ya que el mensaje completo se reconstruye usando la strtr de PHP. Sin embargo, es obligatorio usar la notación %variable% cuando se traduce en plantillas Twig. Así que este es el formato recomendado y el que deberías utilizar en tus aplicaciones.

Como se ha visto, la creación de una traducción es un proceso de dos pasos:

  1. Abstraer el mensaje a traducir procesándolo con el servicio translator.
  2. Crear una traducción del mensaje para cada idioma que soporte la aplicación.

El segundo paso se realiza creando catálogos de mensajes que definen las traducciones para cada uno de los diferentes locales.