Laravel 路由中的页面 slug 如何按语言本地化?
数据小许
结论
{{ __($page->title) }} 会翻译标题文本。route('pages.get', ['slug' => $page->slug]) 则只会把 $page->slug 作为路由参数传入,不会自动翻译。要生成本地化 URL,需要为当前语言提供对应的 slug。若固定路径片段也要翻译,还需单独配置本地化路由路径。
为每种语言保存对应的 slug
如果页面有多个语言版本,可以在数据库中为每种语言保存 slug,也可以使用多语言关联表。生成链接时,先根据当前语言取出对应的 slug,再传给路由:
<a href="{{ route('pages.get', ['slug' => $page->slugFor(app()->getLocale())]) }}">
{{ __($page->title) }}
</a>
slugFor() 是示意方法,需根据项目的数据结构实现。例如,页面记录包含 slug_en 和 slug_zh 字段时,可以按语言选择对应字段:
public function slugFor(string $locale): string
{
return match ($locale) {
'zh' => $this->slug_zh,
'en' => $this->slug_en,
default => $this->slug_en,
};
}
语言代码和默认语言应与项目配置及实际数据一致。如果当前页面没有对应语言的 slug,需要确定是使用默认语言的 slug、跳转到默认语言页面,还是不显示该链接。
让路由包含语言前缀
如果 URL 需要区分语言,可以在路由中加入语言参数:
Route::get('/{locale}/pages/{slug}', [PageController::class, 'show'])
->name('pages.get');
生成 URL 时,同时传入当前语言和对应语言的 slug:
<a href="{{ route('pages.get', [
'locale' => app()->getLocale(),
'slug' => $page->slugFor(app()->getLocale()),
]) }}">
{{ __($page->title) }}
</a>
控制器需要根据收到的语言和 slug 查找页面,并检查该语言是否受支持。例如,slug 保存在单独的翻译表中时,可以按表中的语言和 slug 查询。具体查询方式取决于项目的数据结构。
固定路径片段也要本地化时
传入翻译后的 slug 不会改变 pages 这样的固定路径片段。可以为不同语言定义各自的路由路径,也可以在注册路由时根据语言配置选择路径。路由名称和生成 URL 时使用的参数需要保持一致。
检查实际生成的 URL,确认其中包含预期的语言前缀和对应语言的 slug。标题翻译正常,不能说明路由参数也已本地化。
备注:内容仅供参考。
