我正在使用Symfony 2.8开发WebApp项目。我想在页面中添加不同的语言。根据用户区域设置,所有路由/网址都应从/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}" />
...
</routes>
因此,prefix="/{_locale}"
扩展了公共页面的导入,自动将当前区域设置添加到public_routes.xml
的所有路由中。
这很好用。我现在可以导航到/en
,/en/price
,/en/about
等
然而,仍然必须是一个空的&#34;路线。否则,域本身将不再具有有效路由。 ( BTW :path=""
和path="/"
之间有什么区别吗?)
这是由新的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');
}
因此,如果为请求设置了_locale
,则homeAction
会检查语言是否受支持或引发错误。如果未设置_locale
,则homeAction
会尝试从请求中获取当前_locale(例如,从浏览器接受的语言)。
问题:
上面的解决方案适用于/
的所有calles。在这种情况下,_locale
未设置,因此将呼叫重定向到/someLocale/
,例如`/ EN /.
但是:/somepage
的所有来电也由homeAction
处理。这是因为somepage
被解释为区域设置!因此,使用homeAction
调用$request->attributes->get('_locale') == 'somepage'
。这显然不起作用。
因此,如果有人拨打旧网址/about
而不是新的/en/about
,则路由系统会将此调用与路由home
与_locale about
进行匹配,并且页面不会找到。
Symfony从URL中提取_locale
的确切位置是什么?是否有可能拦截这种提取并使其更智能一点?例如。忽略所有&#34; locales&#34;超过2个字母?
谢谢!
答案 0 :(得分:2)
只需使用routedefinition的requirements
和default
属性
所以你可以为所有路线设置{_locale}
requirements:
_locale: fr|en
defaults: { _locale: fr}
在这个yml示例中,它默认为&#34; fr&#34;如果没有给出_locale,例如/
由于要求about
不匹配_locale