Symfony 5 - 根据浏览器语言翻译网站后重定向

3
我目前正在使用symfony 5开发,并已将我的网站完全翻译成多种语言。我有一个选择语言的按钮,但我希望网站的默认语言是用户的语言(更准确地说是他的浏览器语言设置)。 目前,我已经找到了一种解决方案,但它并不是最优的。 我所做的是,在我的索引中检查用户是否已经浏览过该站点,如果没有,则将其重定向到一个名为“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');
}

我只是在会话中注册变量以更改语言。然后我的问题就出现在这一步之后。当用户在网站上简单地点击语言更改按钮时,他会返回到之前的页面(他没有进入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路由中删除此条件,并找到一种方法在请求的头部添加属性'referer',该属性指向上一页。 我可以在执行redirectToRoutechange_locale之前在我的索引中完成此操作。

1个回答

2
不要使用重定向来设置语言环境。
Symfony关于如何处理用户区域设置的文档提供了一个很好的建议:使用自定义事件监听器代替。还可以阅读在用户会话期间使区域设置“粘性”
您可以使用文档中的示例:
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地址或其他逻辑来获取信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接