Symfony3 在深层链接中添加语言环境

Symfony3 add locale in deeplink

我在 https://symfony.com/doc/current/setup.html

的官方 symfony 文档中的入门部分之后在 symfony3 中创建了一个新站点

一切正常.. 如果我将 mydomain.com 作为 URL,框架添加 /en 或正确的本地。

我的问题是,如果用户对 mydomain 进行深层链接,是否有一种方法。com/blog 框架发现本地不存在,因此它可以添加 url 并将其转换为我的域名。com/en/blog

我没有添加代码,因为它是默认代码。如果您需要,请告诉我。

有多种方法可以做到这一点。可能最简单的方法是让 EventSubscriber 或 -Listener 捕获没有区域设置的请求,然后处理添加该信息。由于您的项目基于演示应用程序,因此您可能需要查看他们的解决方案:https://github.com/symfony/demo/blob/master/src/EventSubscriber/RedirectToPreferredLocaleSubscriber.php

在事件处理程序中执行的步骤大致如下:

  1. 收听 kernel.request 事件
  2. Return 早期基于某些标准,例如主页、设置了带有该语言的 cookie 或其他内容
  3. 通过获取默认语言环境或根据可用语言环境和浏览器确定语言来检测语言header哪种语言最适合(参见:https://github.com/willdurand/Negotiation#language-negotiation
  4. 重定向,将语言环境作为属性添加到请求中,将当前设置的语言写入 cookie,或者您需要做的任何其他更改路由的操作

多亏了@dbrumann,我找到了这个解决方案...可以肯定的是,使用更少的代码可以改进它,但它确实起到了作用。

我更新了 RedirectToPreferredLocaleSubscriber 中的 onKernelRequest 方法 class

public function onKernelRequest(GetResponseEvent $event): void
    {
        $request = $event->getRequest();
        $path = explode('/',$request->getPathInfo());
        $hasLocale = false;
        foreach ($this->locales as $key => $l) {
            if($l == $path[1]){
                $hasLocale = true;
            }
        }
        if(!$hasLocale){
            // Ignore sub-requests and all URLs but the homepage
            if (!$event->isMasterRequest() || '/' !== $request->getPathInfo()) {
                $preferredLanguage = $request->getPreferredLanguage($this->locales);
                if ($preferredLanguage !== $this->defaultLocale) {
                    $url = "";
                    foreach ($path as $key => $p) {
                        if($key > 0){
                            $url .= "/" . $p;
                        }
                    }
                    //print_r('/' . $preferredLanguage . $url);exit;
                    $response = new RedirectResponse('/' . $preferredLanguage . $url);
                    $event->setResponse($response);
                }
            }
            else{
                // Ignore requests from referrers with the same HTTP host in order to prevent
                // changing language for users who possibly already selected it for this application.
                if (0 === mb_stripos($request->headers->get('referer'), $request->getSchemeAndHttpHost())) {
                    return;
                }

                $preferredLanguage = $request->getPreferredLanguage($this->locales);
                if ($preferredLanguage !== $this->defaultLocale) {
                    $response = new RedirectResponse($this->urlGenerator->generate('homepage', ['_locale' => $preferredLanguage]));
                    $event->setResponse($response);
                }
            }
        }
    }