Symfony 2.3, el libro oficial

15.7. Gestionando la configuración regional del usuario

La configuración regional o locale del usuario actual se almacena en la petición y se puede acceder a través del objeto Request:

// accediendo al objeto Request desde un controlador
$request = $this->getRequest();

$locale = $request->getLocale();

$request->setLocale('en_US');

También puedes almacenar el locale en la sesión del usuario (mediante la propiedad especial _locale) en vez de obtenerla cada vez de las peticiones. Si lo haces, las peticiones posteriores tendrán automáticamente el locale almacenado en la sesión.

$this->get('session')->set('_locale', 'en_US');

15.7.1. Configuración regional por defecto

Si la configuración regional no se ha establecido explícitamente en la sesión, se utiliza el valor de la opción de configuración fallback_locale, que por defecto es en (es decir, inglés).

Si lo prefieres, puedes garantizar que la petición del usuario siempre tenga establecido un locale definiendo la opción default_locale del framework:

# app/config/config.yml
framework:
    default_locale: en
<!-- app/config/config.xml -->
<framework:config>
    <framework:default-locale>en</framework:default-locale>
</framework:config>
// app/config/config.php
$container->loadFromExtension('framework', array(
    'default_locale' => 'en',
));

15.7.2. El locale y la URL

Como la configuración regional del usuario se puede almacenar en la sesión, a lo mejor has pensado en utilizar la misma URL para mostrar un recurso en muchos idiomas diferentes en función del idioma de cada usuario.

La URL http://www.ejemplo.com/contact por ejemplo podría mostrar el contenido en inglés para un usuario y en francés para otro. Lamentablemente, esto viola una norma fundamental de la web: que una misma URL debe devolver siempre el mismo recurso, independientemente del usuario. Para acabar de agravar el problema, ¿cuál sería el contenido indexado por los motores de búsqueda para esa URL?

Una práctica mucho mejor es incluir la configuración regional en la propia URL. El sistema de enrutamiento de Symfony puede encargarse de ello al añadir un parámetro especial llamado _locale:

contact:
    path:      /{_locale}/contact
    defaults:  { _controller: AcmeDemoBundle:Contact:index, _locale: en }
    requirements:
        _locale: en|fr|de
<route id="contact" path="/{_locale}/contact">
    <default key="_controller">AcmeDemoBundle:Contact:index</default>
    <default key="_locale">en</default>
    <requirement key="_locale">en|fr|de</requirement>
</route>
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;

$collection = new RouteCollection();
$collection->add('contact', new Route('/{_locale}/contact', array(
    '_controller' => 'AcmeDemoBundle:Contact:index',
    '_locale'     => 'en',
), array(
    '_locale'     => 'en|fr|de',
)));

return $collection;

Cuando utilizas el parámetro especial _locale en una ruta, Symfony2 establece automáticamente el locale del usuario a ese valor y lo guarda en la sesión. En otras palabras, si un usuario visita la URL /es/contact, el locale del usuario se establece automáticamente a es.

Ahora puedes utilizar la configuración regional del usuario para crear rutas hacia otras páginas traducidas en tu aplicación.