Laravel多语言路由头疼?codezero/laravel-localized-routes助你优雅实现国际化

laravel多语言路由头疼?codezero/laravel-localized-routes助你优雅实现国际化

Composer在线学习地址:学习地址

国际化应用中的路由之痛

想象一下,你正在构建一个面向全球用户的 Laravel 网站。你的网站需要支持英语、法语、德语等多种语言。这意味着,对于同一个页面,比如“关于我们”,你可能需要这样的 URL:

/en/about-us/fr/a-propos/de/ueber-uns

如果你的应用中有几十个甚至上百个页面,每个页面都需要为每种语言定义一套路由,那么你的 routes/web.php 文件很快就会变得像一团乱麻。手动管理这些路由不仅效率低下,还容易出现以下问题:

代码重复与臃肿: 为每种语言复制粘贴相似的路由定义。URL 生成复杂: 在视图或控制器中生成特定语言的 URL 时,需要手动拼接语言前缀,或者使用复杂的条件判断。路由参数翻译: 如果路由中包含像 posts/{post:slug} 这样的参数,而 slug 本身也需要根据语言进行翻译,那处理起来更是麻烦。404 页面本地化: 当用户访问不存在的页面时,如何确保 404 页面也是当前语言的?维护成本高: 增加或删除一种语言,或者修改某个路由,都需要改动大量文件。

这些问题让我在国际化开发的道路上举步维艰,直到我遇到了 codezero/laravel-localized-routes

遇见救星:codezero/laravel-localized-routes

codezero/laravel-localized-routes 是一个专为 Laravel 设计的 Composer 包,它提供了一种优雅且便捷的方式来设置、管理和使用本地化路由。它将多语言路由的复杂性封装起来,让你能够以更简洁、更直观的方式定义和使用路由。

它的核心理念是:你只需定义一次路由,这个包就会自动为所有支持的语言生成对应的本地化路由,并处理好语言前缀、域名甚至路由参数的翻译。

如何使用 Composer 解决问题?

首先,我们通过 Composer 将这个强大的工具引入到我们的项目中:

composer require codezero/laravel-localized-routes

安装完成后,Laravel 会自动注册其 ServiceProvider。接下来,我们需要进行一些简单的配置。

1. 发布配置文件

运行以下命令发布其配置文件,你会在 config/localized-routes.php 找到它:

php artisan vendor:publish --provider="CodeZeroLocalizedRoutesLocalizedRoutesServiceProvider" --tag="config"

2. 配置支持的语言环境

config/localized-routes.php 中,你可以定义你的应用支持哪些语言。这非常灵活:

简单语言前缀:

// config/localized-routes.php'supported_locales' => ['en', 'nl', 'fr'],

这会将 /en/about/nl/about 等作为路由前缀。

自定义语言 Slug:

如果你想让语言前缀更具描述性,或者与语言代码不同:

'supported_locales' => [    'en' => 'english-slug',    'nl' => 'dutch-slug',],

自定义域名:

对于更复杂的国际化策略,你甚至可以为每种语言指定独立的域名:

'supported_locales' => [    'en' => 'english-domain.test',    'nl' => 'dutch-domain.test',],

主语言省略 Slug:

为了让主语言的 URL 更简洁,你可以配置省略其语言前缀:

'omitted_locale' => 'en', // 英语路由将没有 /en 前缀

这样,en.example.com/about 就会变成 example.com/about

3. 添加中间件自动更新应用语言环境

为了让 Laravel 应用的语言环境(App::getLocale())根据 URL 自动切换,你需要注册 SetLocale 中间件。请确保它在 StartSession 之后,SubstituteBindings 之前运行,这对于路由模型绑定中的本地化参数解析至关重要。

Laravel 11 及更高版本:

// bootstrap/app.php->withMiddleware(function (Middleware $middleware) {    $middleware->web(remove: [        IlluminateRoutingMiddlewareSubstituteBindings::class,    ]);    $middleware->web(append: [        CodeZeroLocalizedRoutesMiddlewareSetLocale::class,        IlluminateRoutingMiddlewareSubstituteBindings::class,    ]);})

Laravel 10:

// app/Http/Kernel.phpprotected $middlewareGroups = [    'web' => [        //...        IlluminateSessionMiddlewareStartSession::class, // <= 在此之后        //...        CodeZeroLocalizedRoutesMiddlewareSetLocale::class,        IlluminateRoutingMiddlewareSubstituteBindings::class, // <= 在此之前    ],];

4. 注册本地化路由

现在,最核心的部分来了。你只需将路由定义放在 Route::localized() 闭包中,该包就会自动为每种支持的语言注册相应的路由:

// routes/web.phpuse AppHttpControllersAboutController;Route::localized(function () {    Route::get('about', [AboutController::class, 'index'])->name('about');});

有了这个简单的定义,如果你的 supported_locales['en', 'nl'],并且 omitted_localeen,那么它会自动生成:

/about (en.about)/nl/about (nl.about)

这大大减少了路由文件的重复代码!

5. 翻译路由参数(Route Model Binding)

如果你的路由参数也需要本地化,比如 posts/{post:slug},其中 slug 是多语言的,你需要在模型中重写 resolveRouteBinding 方法:

// AppModelsPost.phpuse IlluminateSupportFacadesApp;class Post extends Model{    public function resolveRouteBinding($value, $field = null)    {        $field = $field ?: $this->getRouteKeyName();        if ($field === 'slug') {            // 假设你的 slug 存储在 JSON 字段中,例如 ['en' => 'my-post', 'nl' => 'mijn-bericht']            $field .= '->' . App::getLocale();        }        return $this->where($field, $value)->firstOrFail();    }}

这样,当访问 /en/posts/my-post/nl/posts/mijn-bericht 时,Laravel 就能正确解析到对应的 Post 模型。

6. 翻译硬编码的 URI Slugs

对于像 about/us 这样硬编码的 URI 段,你可能希望它们也能被翻译(例如 over/ons)。这个包集成了 codezero/laravel-uri-translator,提供了 Lang::uri() 宏:

首先,创建语言文件来存储路由翻译:

// lang/nl/routes.phpreturn [    'about' => 'over',    'us' => 'ons',];

然后,在路由定义中使用它:

use AppHttpControllersAboutController;use IlluminateSupportFacadesLang;Route::localized(function () {    Route::get(Lang::uri('about/us'), [AboutController::class, 'index'])->name('about');});

现在,en.about 可能是 /about/us,而 nl.about 就会是 /nl/over/ons

7. 生成本地化 URL

生成 URL 也变得非常简单和智能:

生成当前语言的 URL:

$url = route('about'); // 如果当前语言是 'en' 且省略了前缀,则返回 '/about'

生成特定语言的 URL:

Laravel 的 route() 助手函数被扩展,支持额外的语言参数:

$url = route('about', [], true, 'nl'); // 返回 '/nl/about'

生成当前路由的本地化版本(非常适合语言切换器):

Route::localizedUrl() 宏能自动识别当前路由和参数,并生成指定语言的 URL:

// 假设当前路由是 /en/posts/my-post$enUrl = Route::localizedUrl('en'); // /posts/my-post$nlUrl = Route::localizedUrl('nl'); // /nl/posts/mijn-bericht// 如果路由有多个参数,模型可以实现 ProvidesRouteParameters 接口// 从 getRouteParameters() 方法返回参数值。

这使得构建语言切换器变得异常简单:

@if (Route::isLocalized() || Route::isFallback())    @endif

8. 本地化 404 页面和自动重定向

为了确保 404 页面也是本地化的,并且可以将非本地化 URL 自动重定向到其本地化版本,你可以在 routes/web.php 的末尾注册一个回退路由:

// routes/web.phpRoute::fallback(CodeZeroLocalizedRoutesControllersFallbackController::class);

并在配置文件中开启自动重定向:

// config/localized-routes.php'redirect_to_localized_urls' => true,

这样,如果用户访问 /about-us (非本地化 URL),它会根据当前语言环境自动重定向到 /en/about-us/nl/about-us

优势与实际应用效果

使用 codezero/laravel-localized-routes 之后,我的开发体验得到了显著提升:

极简的路由定义: 告别了为每种语言重复定义路由的噩梦,routes/web.php 变得干净整洁。自动化的语言切换: 中间件自动处理语言环境的检测和设置,无需手动干预。智能的 URL 生成: route() 助手函数和 Route::localizedUrl() 宏让生成特定语言的 URL 变得轻而易举,尤其在构建语言切换器时,效率倍增。无缝的路由参数本地化: 通过模型绑定和 URI 翻译,轻松处理多语言的路由参数和 URI 段。更好的用户体验和 SEO: 统一且友好的多语言 URL 结构,有助于提升用户体验和搜索引擎优化。降低维护成本: 增删语言或修改路由,只需改动少数地方,大大减少了出错的可能性。

这个包让 Laravel 的国际化路由管理从一个令人头疼的难题,变成了一个优雅且高效的解决方案。如果你正在开发一个多语言的 Laravel 应用,我强烈推荐你尝试一下 codezero/laravel-localized-routes,它绝对能让你的开发工作事半功倍!

以上就是Laravel多语言路由头疼?codezero/laravel-localized-routes助你优雅实现国际化的详细内容,更多请关注php中文网其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/136352.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月29日 22:26:02
下一篇 2025年11月29日 22:55:31

相关推荐

  • 如何用dom2img解决网页打印样式不显示的问题?

    用dom2img解决网页打印样式不显示的问题 想将网页以所见即打印的的效果呈现,需要采取一些措施,特别是在使用了bootstrap等大量采用外部css样式的框架时。 问题根源 在常规打印操作中,浏览器通常会忽略css样式等非必要的页面元素,导致打印出的结果与网页显示效果不一致。这是因为打印机制只识别…

    2025年12月24日
    800
  • Bootstrap 中如何让文字浮于阴影之上?

    文字浮于阴影之上 文中提到的代码片段中 元素中的文字被阴影元素 所遮挡,如何让文字显示在阴影之上? bootstrap v3和v5在处理此类问题方面存在差异。 解决方法 在bootstrap v5中,给 元素添加以下css样式: .banner-content { position: relativ…

    2025年12月24日
    000
  • Bootstrap 5:如何将文字置于阴影之上?

    文字重叠阴影 在 bootstrap 5 中,将文字置于阴影之上时遇到了困难。在 bootstrap 3 中,此问题并不存在,但升级到 bootstrap 5 后却无法实现。 解决方案 为了解决这个问题,需要给 元素添加以下样式: .banner-content { position: relati…

    2025年12月24日
    400
  • Bootstrap 5 如何将文字置于阴影上方?

    如何在 bootstrap 5 中让文字位于阴影上方? 在将网站从 bootstrap 3 升级到 bootstrap 5 后,用户遇到一个问题:文字内容无法像以前那样置于阴影层之上。 解决方案: 为了将文字置于阴影层上方,需要给 banner-content 元素添加以下 css 样式: .ban…

    2025年12月24日
    100
  • HTMLrev 上的免费 HTML 网站模板

    HTMLrev 是唯一的人工策划的库专门专注于免费 HTML 模板,适用于由来自世界各地慷慨的模板创建者制作的网站、登陆页面、投资组合、博客、电子商务和管理仪表板世界。 这个人就是我自己 Devluc,我已经工作了 1 年多来构建、改进和更新这个很棒的免费资源。我自己就是一名模板制作者,所以我知道如…

    2025年12月24日
    300
  • 如何使用 Laravel 框架轻松整合微信支付与支付宝支付?

    如何通过 laravel 框架整合微信支付与支付宝支付 在 laravel 开发中,为电商网站或应用程序整合支付网关至关重要。其中,微信支付和支付宝是中国最流行的支付平台。本文将介绍如何使用 laravel 框架封装这两大支付平台。 一个简单有效的方法是使用业内认可的 easywechat lara…

    2025年12月24日
    000
  • Laravel 框架中如何无缝集成微信支付和支付宝支付?

    laravel 框架中微信支付和支付宝支付的封装 如何将微信支付和支付宝支付无缝集成到 laravel 框架中? 建议解决方案 考虑使用 easywechat 的 laravel 版本。easywechat 是一个成熟、维护良好的库,由腾讯官方人员开发,专为处理微信相关功能而设计。其 laravel…

    2025年12月24日
    500
  • 如何在 Laravel 框架中轻松集成微信支付和支付宝支付?

    如何用 laravel 框架集成微信支付和支付宝支付 问题:如何在 laravel 框架中集成微信支付和支付宝支付? 回答: 建议使用 easywechat 的 laravel 版,easywechat 是一个由腾讯工程师开发的高质量微信开放平台 sdk,已被广泛地应用于许多 laravel 项目中…

    2025年12月24日
    000
  • 使用Laravel框架如何整合微信支付和支付宝支付?

    使用 Laravel 框架整合微信支付和支付宝支付 在使用 Laravel 框架开发项目时,整合支付网关是常见的需求。对于微信支付和支付宝支付,推荐采用以下方法: 使用第三方库:EasyWeChat 的 Laravel 版本 建议直接使用现有的 EasyWeChat 的 Laravel 版本。该库由…

    2025年12月24日
    000
  • 如何将微信支付和支付宝支付无缝集成到 Laravel 框架中?

    如何简洁集成微信和支付宝支付到 Laravel 问题: 如何将微信支付和支付宝支付无缝集成到 Laravel 框架中? 答案: 强烈推荐使用流行的 Laravel 包 EasyWeChat,它由腾讯开发者维护。多年来,它一直保持更新,提供了一个稳定可靠的解决方案。 集成步骤: 安装 Laravel …

    2025年12月24日
    100
  • 如何用 CSS 禁止手机端页面屏幕拖动?

    css 禁止手机端屏幕拖动 在手机端浏览网页时,常常会遇到屏幕拖动导致页面内容错乱或无法操作的情况。为了解决这个问题,可以使用 css 的 overflow 属性来禁止屏幕拖动。 解决方案 针对给定的代码,可以在 元素中添加以下 css 样式: 立即学习“前端免费学习笔记(深入)”; body{ov…

    2025年12月24日
    000
  • 如何禁用手机端屏幕拖动功能?

    解决手机端屏幕拖动问题 在移动设备上,当设备屏幕存在内容超出边界时,可以通过拖动屏幕来浏览。但有时,我们希望禁用这种拖动功能,例如当导航菜单展开时。 实施方法 要禁止屏幕拖动,可以为 body 元素添加 overflow:hidden 样式。这将禁用滚动条并阻止屏幕拖动,无论内容是否超出边界。 以下…

    2025年12月24日
    000
  • 如何用纯 CSS 替代 SCSS 中的 @import?

    如何在 css 中替代 scss 中的 @import 在项目中仅有一个文件使用 scss 的情况下,我们可能希望使用纯 css 来替代它。该 scss 文件通常包含对第三方 css 库的导入,如: /* this file is for your main application css. */@…

    2025年12月24日
    000
  • 如何用 CSS 替代 SCSS 中的 @import?

    用 css 替代 scss 中的 @import 在 scss 文件中,@import 语句用于导入其他 css 文件。然而,如果项目中只有一个文件使用 scss,我们可以考虑使用普通 css 来替代它,从而消除对 sass 和 sass-loader 的依赖。 要使用纯 css 替代 scss 文…

    2025年12月24日
    000
  • 如何用纯CSS替代scss中的@import?

    用纯css替代scss中的@import 在一个包含scss文件的项目中,我们可能需要找到一种方法来用纯css替代掉它。为了消除对scss的依赖,可以使用css中的@import指令。 /css中使用@import 纯css中的@import语法与scss中的类似: 立即学习“前端免费学习笔记(深入…

    2025年12月24日
    000
  • 如何构建一个可重复使用的 CSS 容器元素?

    探索可重复使用的 css 容器元素 在前端开发中,css 容器是一个重要的元素,它为应用程序的内容提供了一个可重复使用的布局和样式基础。让我们探讨一下一个典型容器应该包含哪些核心属性。 通常,一个容器元素仅限于定义页面内容的布局和留白。一些常见的属性包括: padding:设置容器内元素与边框之间的…

    2025年12月24日
    000
  • 什么是可重复使用的 CSS 容器?它包含哪些属性?

    什么是可重复使用的 css container? 容器在 css 中扮演着重要的角色,负责容纳页面内容并控制其布局。一个可重复使用的 container 是一组预定义的样式,可以应用于多个组件,以确保一致性和可维护性。 可重复使用的 container 包含哪些属性? 通常,可重复使用的 conta…

    2025年12月24日
    000
  • Bootstrap 4 表格中如何实现列向右对齐?

    表格对齐问题 在bootstrap 4中构建表格时,有时会遇到列不对齐的问题。本文将介绍一个解决此问题的方法,以实现列向右对齐。 问题: 假设我们有一个带有四列的表格,前两列使用 th 标签作为标题,后两列使用 td 标签表示数据。然而,我们希望后两列数据向右对齐。 解决方法: 要解决此问题,我们可…

    2025年12月24日
    000
  • Bootstrap 表格中如何实现列对齐不一致?

    表格设计中的对齐问题 使用 Bootstrap 框架创建表格时,有时会遇到列对齐不一致的问题。例如,将最后两列向右对齐,以下方法可以解决此问题: 将表格设置为 100% 宽度,以覆盖整个容器。为 1、3、4 列设置固定宽度,以确保这些列的对齐。将 2 列设置为自动宽度(不设置宽度),使其自动填充剩余…

    2025年12月24日
    000
  • 如何使用 CSS 将 HTML 表格中的特定列右对齐?

    表格对齐问题:如何将表格中的特定列右对齐? 在 html 表格中,您可以使用 css 样式来控制内容对齐方式。在这种情况下,要将最后两列向右对齐,可以使用以下步骤: 确保表格为 100% 宽度。这将允许表格占用可用空间的全部宽度。设置需要右对齐的列为固定宽度。这将为列分配一个指定宽度,确保内容始终在…

    2025年12月24日
    000

发表回复

登录后才能评论
关注微信