概念
因此,Fluent 支持通过开箱即用的查询字符串进行本地化,但将语言环境附加到 URL 是为 CMS 驱动的页面保留的。通过您的示例,我可以通过/search?l=en 和/search?l=mi 看到正确的结果。
为了允许非 SiteTree 路由的 URL 中的区域设置,我们可以修补 FluentDirectorExtension,它是负责注入 Fluent 路由规则的类,并添加对也应该是可本地化的路由的显式配置的支持。这可以通过添加与上述基本相同的 Director 规则来实现,但在后台将 /search?l=en URL 屏蔽为 /en/search。
我的示例配置是这样的:
TractorCow\Fluent\Extension\FluentDirectorExtension:
static_routes: # Routes that should also allow URL segment based localisation
- 'search//'
这应该与您的 Director.rules 配置中的规则键匹配。
然后我们可以构造新的 URL 以允许支持,并告诉 Director 使用现有的配置控制器,同时透明地传递区域设置的 l 参数。我们需要对每个语言环境都这样做,并且需要在 Fluent 的默认规则之前插入规则。你可以做的一个例子:
diff --git a/src/Extension/FluentDirectorExtension.php b/src/Extension/FluentDirectorExtension.php
index 6ebf1d6..0cdd80b 100644
--- a/src/Extension/FluentDirectorExtension.php
+++ b/src/Extension/FluentDirectorExtension.php
@@ -116,7 +116,10 @@ class FluentDirectorExtension extends Extension
protected function getExplicitRoutes($originalRules)
{
$queryParam = static::config()->get('query_param');
+ $staticRoutes = static::config()->get('static_routes');
$rules = [];
+ $prependRules = []; // we push these into the $rules before default fluent rules
+
/** @var Locale $localeObj */
foreach (Locale::getCached() as $localeObj) {
$locale = $localeObj->getLocale();
@@ -138,8 +141,22 @@ class FluentDirectorExtension extends Extension
'Controller' => $controller,
$queryParam => $locale,
];
+
+ // Include opt-in static routes
+ foreach ($staticRoutes as $staticRoute) {
+ // Check for a matching rule in the Director configuration
+ if (!isset($originalRules[$staticRoute])) {
+ continue;
+ }
+
+ $prependRules[$url . '/' . $staticRoute] = [
+ 'Controller' => $originalRules[$staticRoute],
+ $queryParam => $locale,
+ ];
+ }
}
- return $rules;
+
+ return array_merge($prependRules, $rules);
}
/**
如果您在 updateRules() 方法的末尾调试 $rules,您会看到 Fluent 现在已在每个语言环境中为该路由注入了新规则:
'en/search//' =>
array (size=2)
'Controller' => string 'App\Controllers\SearchController' (length=42)
'l' => string 'en_NZ' (length=5)
'mi/search//' =>
array (size=2)
'Controller' => string 'App\Controllers\SearchController' (length=42)
'l' => string 'mi_NZ' (length=5)
实施
一旦我可以用一些单元测试来备份它,我将为此更改制定一个拉取模块的请求,但与此同时,您可以通过在项目代码中使用注入器覆盖来实现这一点,并扩展受保护的getExplicitRoutes 方法来实现上述更改:
SilverStripe\Core\Injector\Injector:
TractorCow\Fluent\Extension\FluentDirectorExtension:
class: MyFluentDirectorExtension
class MyFluentDirectorExtension extends FluentDirectorExtension
{
protected function getExplicitRoutes($originalRules)
{
$rules = parent::getExplicitRoutes($originalRules);
$staticRoutes = static::config()->get('static_routes');
$queryParam = static::config()->get('query_param');
$prependRules = [];
// Include opt-in static routes
foreach (Locale::getCached() as $localeObj) {
foreach ($staticRoutes as $staticRoute) {
$locale = $localeObj->getLocale();
$url = urlencode($localeObj->getURLSegment());
// Check for a matching rule in the Director configuration
if (!isset($originalRules[$staticRoute])) {
continue;
}
$prependRules[$url . '/' . $staticRoute] = [
'Controller' => $originalRules[$staticRoute],
$queryParam => $locale,
];
}
}
return array_merge($prependRules, $rules);
}
}