Symfony 5 - 基于浏览器语言的网站翻译后重定向
Symfony 5 - Redirection after website translation based on browser language
我目前正在开发 symfony 5,我已经将我的网站完全翻译成多种语言。我有一个 select 语言的按钮,但我希望网站的默认语言是用户的语言(更准确地说是他的浏览器)。
目前我找到了一个解决方案,但它根本不是最优的。
我所做的是,在我的索引中,我检查用户之前是否已经浏览过该站点,如果没有,我将他重定向到 change_locale
路由,该路由会将相关语言作为参数(只有第一次访问才进入条件)
public function index(Request $request): Response
{
// If this is the first visit to the site, the default language is set according to the user's browser language
if (!$request->hasPreviousSession()) {
return $this->redirectToRoute('change_locale', ['locale' => strtolower(str_split($_SERVER['HTTP_ACCEPT_LANGUAGE'], 2)[0])]);
}
return $this->render('accueil/index.html.twig');
}
这里我只是在session中注册了变量来改变语言。
而我的问题就在这一步之后。当用户简单地点击站点上的语言更改按钮时,他会返回到上一页(他没有输入 if)。
但是,如果他是第一次来该站点,他会从索引中重定向,当他来到这条路线时,他会输入条件 if (!$request->hasPreviousSession())
并且...这就是问题所在。因为如果他之前没有访问过任何东西,我无法将他重定向到他正在访问的页面。
/**
* @Route("/change-locale/{locale}", name="change_locale")
*/
public function changeLocale($locale, Request $request)
{
$request->getSession()->set('_locale', $locale); // Storing the requested language in the session
// If it's the first page visited by the user
if (!$request->headers->get('referer')) {
return $this->redirectToRoute('index');
}
// Back to the previous page
return $this->redirect($request->headers->get('referer'));
}
所以我尝试从我的 change_locale
路由中删除此条件,并找到一种方法在请求的 header 中添加指向上一页的属性 'referer'
。
在执行 redirectToRoute
到 change_locale
.
之前,我可以在我的索引中执行此操作
不要使用重定向来设置语言环境。
Symfony 关于 How to Work with the User’s Locale has a great suggestion: use a custom event listener instead. Also read Making the Locale “Sticky” during a User’s Session 的文档。
您可以使用文档中的这个示例:
class LocaleSubscriber implements EventSubscriberInterface
{
private $defaultLocale;
public function __construct(string $defaultLocale = 'en')
{
$this->defaultLocale = $defaultLocale;
}
public function onKernelRequest(RequestEvent $event)
{
$request = $event->getRequest();
if (!$request->hasPreviousSession()) {
return;
}
// try to see if the locale has been set as a _locale routing parameter
if ($locale = $request->attributes->get('_locale')) {
$request->getSession()->set('_locale', $locale);
} else {
// if no explicit locale has been set on this request, use one from the session
$request->setLocale($request->getSession()->get('_locale', $this->defaultLocale));
}
}
public static function getSubscribedEvents()
{
return [
// must be registered before (i.e. with a higher priority than) the default Locale listener
KernelEvents::REQUEST => [['onKernelRequest', 20]],
];
}
}
还有一些免费建议:在 onKernelRequest
方法中,您可以使用 HTTP_ACCEPT_LANGUAGE
来查看用户可能使用的语言,但是(与所有其他用户输入一样!)它可能不可用或不可靠.您可能希望使用来自用户 IP 地址或其他逻辑的信息。
我目前正在开发 symfony 5,我已经将我的网站完全翻译成多种语言。我有一个 select 语言的按钮,但我希望网站的默认语言是用户的语言(更准确地说是他的浏览器)。 目前我找到了一个解决方案,但它根本不是最优的。
我所做的是,在我的索引中,我检查用户之前是否已经浏览过该站点,如果没有,我将他重定向到 change_locale
路由,该路由会将相关语言作为参数(只有第一次访问才进入条件)
public function index(Request $request): Response
{
// If this is the first visit to the site, the default language is set according to the user's browser language
if (!$request->hasPreviousSession()) {
return $this->redirectToRoute('change_locale', ['locale' => strtolower(str_split($_SERVER['HTTP_ACCEPT_LANGUAGE'], 2)[0])]);
}
return $this->render('accueil/index.html.twig');
}
这里我只是在session中注册了变量来改变语言。
而我的问题就在这一步之后。当用户简单地点击站点上的语言更改按钮时,他会返回到上一页(他没有输入 if)。
但是,如果他是第一次来该站点,他会从索引中重定向,当他来到这条路线时,他会输入条件 if (!$request->hasPreviousSession())
并且...这就是问题所在。因为如果他之前没有访问过任何东西,我无法将他重定向到他正在访问的页面。
/**
* @Route("/change-locale/{locale}", name="change_locale")
*/
public function changeLocale($locale, Request $request)
{
$request->getSession()->set('_locale', $locale); // Storing the requested language in the session
// If it's the first page visited by the user
if (!$request->headers->get('referer')) {
return $this->redirectToRoute('index');
}
// Back to the previous page
return $this->redirect($request->headers->get('referer'));
}
所以我尝试从我的 change_locale
路由中删除此条件,并找到一种方法在请求的 header 中添加指向上一页的属性 'referer'
。
在执行 redirectToRoute
到 change_locale
.
不要使用重定向来设置语言环境。
Symfony 关于 How to Work with the User’s Locale has a great suggestion: use a custom event listener instead. Also read Making the Locale “Sticky” during a User’s Session 的文档。
您可以使用文档中的这个示例:
class LocaleSubscriber implements EventSubscriberInterface
{
private $defaultLocale;
public function __construct(string $defaultLocale = 'en')
{
$this->defaultLocale = $defaultLocale;
}
public function onKernelRequest(RequestEvent $event)
{
$request = $event->getRequest();
if (!$request->hasPreviousSession()) {
return;
}
// try to see if the locale has been set as a _locale routing parameter
if ($locale = $request->attributes->get('_locale')) {
$request->getSession()->set('_locale', $locale);
} else {
// if no explicit locale has been set on this request, use one from the session
$request->setLocale($request->getSession()->get('_locale', $this->defaultLocale));
}
}
public static function getSubscribedEvents()
{
return [
// must be registered before (i.e. with a higher priority than) the default Locale listener
KernelEvents::REQUEST => [['onKernelRequest', 20]],
];
}
}
还有一些免费建议:在 onKernelRequest
方法中,您可以使用 HTTP_ACCEPT_LANGUAGE
来查看用户可能使用的语言,但是(与所有其他用户输入一样!)它可能不可用或不可靠.您可能希望使用来自用户 IP 地址或其他逻辑的信息。