language - symfony4 translations
Symfony2 detección de localización incorrecta? (4)
Hoy investigué más detenidamente el código porque estaba experimentando el mismo problema que usted, y parece que el lenguaje proviene de Session::getLocale()
. Pero Symfony2 nunca llama a Session::setLocale()
y establece el miembro de locale
del objeto Session
. Una búsqueda en google para "setlocale de la sesión symfony2" lleva a este § de la documentación
Así que terminé poniendo esta línea encima del controlador en el que estaba trabajando, y funcionó:
$this->getRequest()->getSession()->setLocale(
$this->getRequest()->getPreferredLanguage());
Ahora supongo que esto no es aceptable, porque no vas a agregar esto encima de todos y cada uno de los controladores. Además, esto no debe hacerse para cada solicitud, solo debe hacerse para la primera, cuando el usuario aún no tiene sesión. Si alguien sabe cómo hacerlo, no dude en editar esta respuesta.
Siguiendo la guía de Symfony2 sobre traducción, encontré que la configuración local inferida de los encabezados http (almacenada en $this->get(''session'')->getLocale()
) es incorrecta (lo envió, inferimos en ):
Alojar localhost User-Agent Mozilla / 5.0 (Windows NT 6.1; WOW64; rv: 7.0.1) Gecko / 20100101 Firefox / 7.0.1 Aceptar texto / html, application / xhtml + xml, application / xml; q = 0.9, / ; q = 0.8 Aceptar-Idioma it-it, it; q = 0.8, en-us; q = 0.5, en; q = 0.3
¿Es esto un comportamiento normal? ¿O debería establecer algo para que la localización funcione de la caja?
Escribí LocaleListener que no lo redirecciona a una url específica de la configuración regional; sin embargo, establece la configuración regional para usted;)
Código en los servicios.yml
services:
acme.demobundle.listener.request:
class: Namespace/LocaleListener
tags: [{ name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: -255 }]
arguments: [ @service_container, [ ''en'', ''fr'', ''de'', ''it'', ''es'' ] ]
y el oyente real:
class LocaleListener
{
protected $container;
protected $availableLocales;
public function __construct(/Symfony/Component/DependencyInjection/Container $container, $availableLocales) {
$this->container = $container;
$this->availableLocales = $availableLocales;
}
public function onKernelRequest(GetResponseEvent $e) {
$req = $e->getRequest();
$locale = $req->getPreferredLanguage($this->availableLocales);
$session = $this->container->get(''session'');
$session->setLocale($locale);
}
}
Puede registrar el oyente como sigue:
use Symfony/Component/DependencyInjection/ContainerInterface;
use Symfony/Component/HttpKernel/HttpKernelInterface;
use Symfony/Component/HttpKernel/Event/GetResponseEvent;
class LocaleListener
{
private $container;
private $defaultLocale;
public function __construct(ContainerInterface $container, $defaultLocale = ''nl'')
{
$this->container = $container;
$this->defaultLocale = $defaultLocale;
}
public function onKernelRequest(GetResponseEvent $event)
{
if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
return;
}
if (!$this->container->has(''session'')) {
return;
}
$session = $this->container->get(''session'');
$session->setLocale($this->defaultLocale);
}
}
( esencia )
Justo después de la etapa de configuración de la sesión marco:
<service id="my.event_listener.locale_listener" class="MyBundle/MyEventListener/LocaleListener">
<tag name="kernel.event_listener" event="kernel.request" method="onKernelRequest" priority="100" />
<argument type="service" id="service_container" />
</service>
( esencia )
según HTTP-Standard, debe usar una URL diferente para cada versión traducida de la página. Lo que queda es una acción simple que deducirá la configuración regional más adecuada de la solicitud y redirigirá a la página correspondiente:
/**
* @Route("/")
*/
public function localeRedirectAction() {
/* @var $request /Symfony/Component/HttpFoundation/Request */
/* @var $session /Symfony/Component/HttpFoundation/Session */
$req = $this->getRequest();
$session = $this->get(''session'');
$session->setLocale($req->getPreferredLanguage(array(''de'', ''en'')));
return $this->redirect($this->generateUrl(''home''));
}
si necesita hacer esto para cualquier página, básicamente deberá hacer lo mismo, pero dentro de un Listener para kernel.request
-Event. Para poder llamarlo de manera confiable después de que el enrutador de ruta hizo su trabajo, debe establecer la priority
del oyente en un valor <0:
# services.yml
services:
my_locale_listener:
class: Namespace/LocaleListener
tags: [{ name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: -255 }]
arguments: [ @service_container, [ ''en'', ''fr'', ''de'', ''es'', ''it'' ] ]
el oyente se vería así:
class LocaleListener {
public function __construct($container, $availableLocales) {
$this->container = $container;
$this->availableLocales = $availableLocales;
}
public function onKernelRequest(GetResponseEvent $e) {
$req = $e->getRequest();
$locale = $req->getPreferredLanguage($this->availableLocales);
// generate a new URL from the current route-name and -params, overwriting
// the current locale
$routeName = $req->attributes->get(''_route'');
$routeParams = array_merge($req->attributes->all(), array(''_locale'' => $locale));
$localizedUrl = $this->container->get(''router'')->generateUrl($routeName, $routeParams);
$e->setResponse(new RedirectResponse($localizedUrl));
}
}
PD. No estoy del todo seguro de que este código realmente funcione, pero debería dar una idea básica de cómo se podría hacer esto.