当前位置: 首页 > 知识库问答 >
问题:

Symfony路由:何时/何地_locale属性集

慕璞
2023-03-14

我正在使用Symfony 2.8开发一个WebApp项目。我想在页面中添加不同的语言。根据用户的区域设置,所有路由/url应从/some/url更改为/locale/some/url,例如/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>

以及公共路线。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}" />

    ...
</routes>

因此,公共页面的导入被扩展为前缀=“/{u locale}”,它自动将当前区域设置添加到公共路径的所有路径中。xml

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

然而,这条路线仍然必须是“空”路线。否则域本身将不再具有有效路由。(顺便问一下:path=“path=“/”)之间有什么区别吗?)

这由新的home\u重定向路由及其控制器处理:

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');
}

因此,如果为请求设置了\u locale,则homeAction会检查该语言是否受支持或引发错误。如果未设置\u locale,则homeAction会尝试从请求中获取当前的\u locale(例如,从浏览器接受的语言)。

问题:上述解决方案对所有调用/的人都有效。在这种情况下,\u locale未设置,因此调用被重新定向到/someLocale/,例如,`/en/。

但是:对/somepage的所有调用也由homeAction处理。这是因为somepage被解释为locale!因此,homeAction将通过$request调用-

因此,如果有人调用旧的URL/about而不是新的/en/about,路由系统会将此调用与routehome和_localeabout匹配,并且找不到页面。

Symfony从URL中提取_locale的确切位置?有没有可能拦截这次提取,让它变得更聪明一点?例如,忽略所有超过2个字母长的“区域设置”?

谢谢!


共有1个答案

谢翰学
2023-03-14

只需使用路由定义的要求默认属性

因此,您可以为所有路由设置{u locale}

  requirements:
    _locale: fr|en
  defaults: { _locale: fr}

在这个yml示例中,如果没有给出_locale,它默认为fr,例如/,并且由于要求about不能匹配为_locale

 类似资料:
  • (以防你看过我的上一个问题:不要混淆问题的第一部分/引言是相同的。最后的问题是不同的:) 我正在使用Symfony 2.8开发一个WebApp项目。我想在页面中添加不同的语言。根据用户的区域设置,所有路由/url应从更改为/locale/some/url

  • 我有一个i18n项目在Symfony 4.1上运行。 我想实现一些路由,如: /= 在本文之后,我将使用注释处理路由,并为注释路由设置全局前缀: 这样,从'.../src/Controller/'注释中定义的所有路由都带有前缀,这导致我的“选择语言”页面和主页之间的冲突。 我想从i18n前缀中排除“选择语言”页面,这样当主页可以停留在 /fr或 /en.时,我就可以使用“/”了 有什么办法可以做到

  • 我编写了一个具有以下签名的处理程序: 如何模拟FormFactory和路由器? 我尝试了以下几点: 但我收到以下错误: AppBundle\Tests\Handler\SetUpHandlerTest::传递给Symfony\Bundle\FrameworkBundle\Routing\Router::\uu construct()的testConstructor参数1必须实现接口Symfony\

  • 我试图设置Symfony3代码库与FOS REST捆绑和我最终得到没有路由发现错误 AppBundle\Resources\config\api路由。yml app\config\routing.yml 控制器 我想集成rest api路由的版本控制。你能告诉我这个错误是什么吗?我该如何纠正这个错误?

  • 我将在我的Symfony 2应用程序中创建一个模块系统。每个模块都是一个捆绑包。 我不知道如何我可以动态(在我的服务代码)加载路由文件(例如。Acme某些ModuleBundle/Resources/config/routing.yml),并使用一些前缀(或主机)应用它们。就像在app/config/routing.yml中嵌入代码一样: 有什么解决办法吗?

  • 我在Symfony 4应用程序中找不到有关全局路由前缀的任何信息。我唯一发现的是用注释控制器。但我不使用注释,我需要所有控制器都具有相同的前缀。 现在我可以在S3中这样在文件: 但是S4是没有捆绑的,我不能做同样的事情——我必须创建一个我不需要的捆绑。 是否可以在Symfony 4中定义一个全局路由前缀,或者我将在每个根目录前添加前缀/创建一个自定义路由加载器,尤其是在YAML中配置路由时?