2011-10-07 19 views

Respuesta

11

es necesario llamar a $this->get('session')->setLocale($locale) (reemplace 'sesión' por 'solicitud' para Symfony 2.1) dentro de su controlador.

He creado un formulario, a la que pasa una matriz de idiomas:

<?php 
class LanguageType extends AbstractType 
{ 
    public function buildForm(FormBuilder $builder, array $options) 
    { 
     $langs = $options['languages']; 
     $langs = array_combine($langs, $langs); 
     foreach ($langs as &$lang) { 
      $lang = \Locale::getDisplayName($lang); 
     } 

     $builder->add('language', 'choice', array(
      'choices' => $langs, 
      'required' => false, 
     )); 
    } 

    public function getDefaultOptions(array $options) 
    { 
     return array(
      'languages' => array('fr_FR', 'en_GB'), 
      'csrf_protection' => false, 
     ); 
    } 

    public function getName() 
    { 
     return 'my_language'; 
    } 
} 

que entregar esta forma a una acción separada en un controlador, en el que establecer la configuración regional y regresar a una redirección última página:

<?php 
class LanguageController extends Controller 
{ 
    public function switchLanguageAction() 
    { 
     $form = $this->get('form.factory')->create(
      new LanguageType(), 
      array('language' => $this->get('session')->getLocale()), 
      array('languages' => $this->container->getParameter('roger.admin.languages', null)) 
     ); 

     $request = $this->get('request'); 
     $form->bindRequest($request); 
     $referer = $request->headers->get('referer'); 

     if ($form->isValid()) { 
      $locale = $form->get('language')->getData(); 
      $router = $this->get('router'); 

      // Create URL path to pass it to matcher 
      $urlParts = parse_url($referer); 
      $basePath = $request->getBaseUrl(); 
      $path = str_replace($basePath, '', $urlParts['path']); 

      // Match route and get it's arguments 
      $route = $router->match($path); 
      $routeAttrs = array_replace($route, array('_locale' => $locale)); 
      $routeName = $routeAttrs['_route']; 
      unset($routeAttrs['_route']); 

      // Set Locale 
      $this->get('session')->setLocale($locale); 

      return new RedirectResponse($router->generate($routeName, $routeAttrs)); 
     } 

     return new RedirectResponse($referer); 
    } 
} 

funciona con cualquier localización válida (los pases como opción de 'lenguaje', mientras que la creación de su forma), a condición de que la extensión Intl PHP está habilitado. Si no es así, deberá reemplazar \Locale::getDisplayName($lang) por una lista de nombres de configuración regional creada manualmente.

+0

Solo tenga cuidado: el referrer puede ser anulado por algunos geeks, luego '$ router-> match()' lanzará una excepción porque no habrá coincidencia.Un repliegue podría ser bueno aquí :-) –

5

No he hecho esto con un formulario, sino simplemente con pequeñas imágenes en la parte superior de la pantalla. Cada bandera es un enlace a la página actual, pero con el código de idioma de dos letras en la URL reemplazado por el idioma de la bandera respectiva. Mi plantilla de diseño tiene el siguiente código:

La función replaceLanguageInUrl se define en mi clase de la extensión de la ramita:

public function getFunctions() 
{ 
    return array(
     'replaceLanguageInUrl' => new \Twig_Function_Method($this, 'replaceLanguageInUrl'), 
    ); 
}  

public function replaceLanguageInUrl($currentLanguage, $newLanguage, $url) 
{ 

    //EDIT BEGIN 
    if (strpos($url,$currentLanguage) == false) { 
     $url = getBaseUrl($url).'/'.$currentLanguage; 
    } 
    //EDIT END 
    return str_replace('/' . $currentLanguage . '/', '/' . $newLanguage . '/', $url); 
} 

Cuando se hace clic en una bandera, se carga la misma página, pero en el nuevo idioma . Esto también configurará automáticamente el nuevo idioma en la sesión.

2

Lo hice con el local también, pero algo más simple que la solución de wdev, utilicé algunas imágenes (banderas) como botones. Cuando se hace clic en la bandera, se establece la nueva configuración regional y la página se actualiza (con una redirección) con el nuevo idioma. Necesita usar Symfony's translation system. Aquí está el código:

controlador:

public function englishAction(Request $request) 
{ 
    $this->get('session')->setLocale('en_US'); 
    return $this->redirect($request->headers->get('referer')); 
} 

public function chineseAction(Request $request) 
{ 
    $this->get('session')->setLocale('zh_CN'); 
    return $this->redirect($request->headers->get('referer')); 
} 

public function frenchAction(Request $request) 
{ 
    $this->get('session')->setLocale('fr_FR'); 
    return $this->redirect($request->headers->get('referer')); 
} 

Plantilla:

<ul class="nav pull-right"> 
    <li> 
      <a href="{{ path('english') }}"><img src="{{ asset('bundles/fkmywebsite/images/flag-en.png') }}" alt="English Language" height="30" width="18" /></a> 
    </li> 
    <li> 
      <a href="{{ path('chinese') }}"><img src="{{ asset('bundles/fkmywebsite/images/flag-cn.jpg') }}" alt="Chinese Language" height="30" width="18" /></a> 
    </li> 
    <li> 
     <a href="{{ path('french') }}"><img src="{{ asset('bundles/fkmywebsite/images/flag-fr.png') }}" alt="French Language" height="30" width="18" /></a> 
    </li> 
</ul> 

Editar: Esta solución funciona con Symfony2.0, para comprobar Symfony2.1 this question

31

La forma más fácil He encontrado que es hacerlo directamente en la plantilla de ramas. Al menos, funciona con 2,2:

<ul class="lang-menu"> 
    <li><a href="{{ path(app.request.get('_route'), app.request.get('_route_params')|merge({'_locale': 'ca'})) }}">Català</a></li> 
    <li><a href="{{ path(app.request.get('_route'), app.request.get('_route_params')|merge({'_locale': 'en'})) }}">English</a></li> 
</ul> 
+0

solución genial y liviana !! – eav

+0

no funcionan para mí, error de conversión en algunas páginas "Se ha lanzado una excepción durante el procesamiento de una plantilla (" No se puede generar una URL para la ruta especificada "" ya que dicha ruta no existe. ")" Aparece ruta no recept la url –

+0

Funciona muy bien para mí. P: ¿Dónde lo aprendes, dentro del documento oficial (el libro de Symfony2)? – mario