【问题标题】:Redirect all routes without _locale to new routes including _locale in Symfony 2.8将所有没有 _locale 的路由重定向到新的路由,包括 Symfony 2.8 中的 _locale
【发布时间】:2016-02-04 15:05:28
【问题描述】:

(以防你访问过我之前的问题:不要混淆问题的第一部分/引言是相同的。最后的问题不同:) p>

我正在使用 Symfony 2.8 开发一个 WebApp 项目。我想在页面中添加不同的语言。根据用户区域设置,所有路由/URL 应从 /some/url 更改为 /locale/some/url, e.g./en/some/url`。

在添加语言之前,主路由文件如下所示:

<?xml version="1.0" encoding="UTF-8" ?>

<routes xmlns="http://symfony.com/schema/routing"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">

    <!-- Routes for the public pages -->
    <import
        resource="@AppBundle/Resources/config/routing/public_routes.xml" />

    ...
</routes>

public_routes.xml的内容如下:

<?xml version="1.0" encoding="UTF-8" ?>

<routes xmlns="http://symfony.com/schema/routing"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">

    <route id="home" path="" methods="GET">
        <default key="_controller">AppBundle:Default:home</default>
    </route>

    <route id="public_price" path="/price" methods="GET">
        <default key="_controller">AppBundle:Default:price</default>
    </route>

    <route id="public_about" path="/about" methods="GET">
        <default key="_controller">AppBundle:Default:about</default>
    </route>

    ...
</routes>

到目前为止,一切都很简单。现在我在路由中添加了以下内容以添加本地化:

<?xml version="1.0" encoding="UTF-8" ?>

<routes xmlns="http://symfony.com/schema/routing"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">

    <!-- Home route to redirect to the right route -->
    <route id="home_redirect" path="" methods="GET">
        <default key="_controller">AppBundle:Default:home</default>
    </route>

    <!-- Routes for the localized public pages -->
    <import
        resource="@AppBundle/Resources/config/routing/public_routes.xml"
        prefix="/{_locale}" >

        <requirement key="_locale">en|fr|es</requirement>
        <default key="_locale">en</default>        
     </import>

    ...
</routes>

因此,公共页面的导入使用prefix="/{_locale}" 进行了扩展,它会自动将当前语言环境添加到来自public_routes.xml 的所有路由。

这很好用。我现在可以导航到/en/en/price/en/about 等。

为了能够仍然导航到“空”路由(没有任何附加路径的域),我添加了 home_redirect 路由及其控制器:

public function homeAction(Request $request) {
    $locale = $request->attributes->get('_locale');
    if (!$locale) {
        // Try to get the preferred language from the request
        $locale = MySettings::getLanguage($request);               
        return $this->redirectToRoute('home', array('_locale' => $locale));
    } elseif (!MySettings::checkLanguage($locale)) {
        // Invalid Locale...
        throw $this->createNotFoundException();
    }

    return $this->render('AppBundle:Default:homepage.html.twig');
}

因此,如果为请求设置了_localehomeAction 会检查该语言是否受支持或抛出错误。如果未设置_localehomeAction 会尝试从请求中获取当前的 _locale(例如,从浏览器接受的语言中)。

如果调用“/”,用户会自动重定向到/en/fr 或任何当前本地。

这适用于主页,但我希望对所有“旧”路由都实现相同的效果,例如 /about/price

当然,我可以添加 about_redirect 路由,就像我添加了 home_redirect 路由一样。但是对所有旧路线都这样做会非常麻烦和丑陋。

有没有更好、更优雅、更自动化的解决方案?

谢谢!

【问题讨论】:

    标签: php symfony localization routing


    【解决方案1】:

    您可以添加侦听器来检查是否设置了语言环境。

    $kernel->getContainer()->get('event_dispatcher')->addListener(\Symfony\Component\HttpKernel\KernelEvents::REQUEST, function($event) {
        if ($event->getRequestType() != \Symfony\Component\HttpKernel\HttpKernelInterface::MASTER_REQUEST) return;
    
        $request = $event->getRequest();
        $locale = $request->attributes->get('_locale');
        if (!$locale) {
            // Try to get the preferred language from the request
            $locale = MySettings::getLanguage($request);
            return new \Symfony\Component\HttpFoundation\RedirectResponse('/' . $locale . '/' . ltrim($request->getRequestUri(), '/'));
        } elseif (!MySettings::checkLanguage($locale)) {
            // Invalid Locale...
            throw new \Symfony\Component\HttpKernel\Exception\NotFoundHttpException();
        }
    });
    
    ....
    
    $response = $kernel->handle($request);
    

    【讨论】:

      猜你喜欢
      • 2016-02-06
      • 1970-01-01
      • 2020-10-27
      • 2021-01-23
      • 2012-07-31
      • 1970-01-01
      • 2015-11-24
      • 1970-01-01
      • 2018-08-13
      相关资源
      最近更新 更多