如何在 Eloquent 中添加多语言支持

发布于 作者:

How To Add Multilingual Support to Eloquent image

您知道世界上有许多国家拥有不止一种官方语言吗?例如,我的祖国比利时有三种:法语、荷兰语和德语。大多数比利时人也说英语。

Laravel 的 Eloquent ORM 是 Laravel 中非常强大的部分。不幸的是,它本身并不提供对多语言模型的支持。自己添加该功能并不难。

首先,让我们看看一个完全没有多语言支持的迁移

Schema::create('articles', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->text('text');
$table->timestamps();
});

我们可以轻松地通过添加特定语言的列来使表存储多种语言

Schema::create('articles', function (Blueprint $table) {
$table->increments('id');
$table->string('name_en');
$table->text('text_en');
$table->string('name_fr');
$table->text('text_fr');
$table->boolean('online');
$table->timestamps();
});

现在,这个表支持存储英语和法语文本。但是,这种方法有一个显著的缺点:每次想要添加对新语言的支持时,都需要在所有支持多语言的表中添加字段。当语言数量开始增长或存在许多多语言表时,这将非常繁琐。

更好的方法是将需要翻译的字段分离到另一个表中。

Schema::create('articles', function (Blueprint $table) {
$table->increments('id');
$table->boolean('online');
$table->timestamps();
});
 
Schema::create('article_translations', function (Blueprint $table) {
$table->increments('id');
$table->integer('article_id')->unsigned();
$table->string('locale')->index();
 
$table->string('name');
$table->text('text');
 
$table->unique(['article_id','locale']);
$table->foreign('article_id')->references('id')->on('articles')->onDelete('cascade');
});

使用此迁移,您无需在应用程序需要支持其他语言时创建额外的字段。

locale 字段用于确定存储记录的语言。在本文的后续示例中,我们将在该字段中存储一个 ISO 代码。

添加具有级联删除的外部键将确保当 articles 表中的记录被删除时,它对应的翻译也将被删除。

好的,现在数据库已经准备好存储可翻译的内容,让我们考虑一下我们希望如何处理它。

$frenchText = $article->getTranslation('fr')->text;

这很好,也很易读。但我们可以做得更好。如果文章模型在应用程序的区域设置是法语时返回文本的法语翻译,将会非常有用

app()->setLocale('fr');
$frenchText = $article->text;

这将使处理可翻译数据变得容易得多。考虑以下小型视图

The article with title {{ $article->title }} is {{ $this->online ? 'online' : 'offline' }}.

请注意,使用翻译后的字段和未翻译的字段之间没有任何区别。不错!

您可以自己创建允许这种行为的函数,但 Dimitris Savvopoulos 创建了一个名为 laravel-translatable 的包,它可以完成所有这些以及更多功能。我在每个项目中都使用它。

安装服务提供者 后,您必须更新模型以使用 Translatable 特性。该模型还应具有一个 $translatableAttributes 属性,该属性包含一个数组,其中包含可翻译的字段的名称

// app/Article.php
class Article extends Model
{
use \Dimsav\Translatable\Translatable;
 
public $translatedAttributes = ['name', 'text'];
 
...
}
 
// app/ArticleTranslation.php
class ArticleTranslation extends Model
{
public $timestamps = false;
 
...
}

现在所有设置都已完成,我们可以存储一些新的可翻译文章。如果您正在按照操作步骤进行,只需将此路由添加到您的 Laravel 应用程序中即可。

Route::get('create', function($locale) {
$article = new Article();
$article->online = true;
$article->save();
 
foreach (['en', 'nl', 'fr', 'de'] as $locale) {
$article->translateOrNew($locale)->name = "Title {$locale}";
$article->translateOrNew($locale)->text = "Text {$locale}";
}
 
$article->save();
 
echo 'Created an article with some translations!';
});

浏览到“/create”后,查看数据库,您会发现 articles 表中包含一条记录。article_translations 表包含三条记录:上面示例中每个区域设置一条。

现在,让我们检索翻译。将此路由添加到您的 Laravel 应用程序中

Route::get('{locale}', function($locale) {
app()->setLocale($locale);
 
$article = Article::first();
 
return view('article')->with(compact('article'));
});

添加一个 article.blade.php 视图,内容如下

<h1>{{ $article->name }}</h1>
{{ $article->text }}

浏览到“/en”,您会看到文章的英语翻译。浏览到“/nl”、“/fr”或“/de”以查看这些区域设置的本地化文章。

恭喜!您现在已经学会了如何向 Eloquent 模型添加多语言支持。我创建了一个 包含此帖子所有示例的 GitHub 存储库。如果您想了解更多信息,我建议您阅读 Dimitris 的包的 README 文件中的示例。仍然渴望了解更多知识?深入研究他的包代码。它并不难理解,而且您会从中吸取很多知识。

Freek Van der Herten photo

PHP 开发人员,Spatie.be 的 Laravel 爱好者、博主和包创建者。

Cube

Laravel 新闻稿

加入 40,000 多名其他开发人员,不错过任何新技巧、教程等信息。

Laravel Forge logo

Laravel Forge

轻松创建和管理您的服务器,并在几秒钟内部署您的 Laravel 应用程序。

Laravel Forge
Tinkerwell logo

Tinkerwell

Laravel 开发人员必备的代码运行器。使用 AI、自动完成和对本地和生产环境的即时反馈进行测试。

Tinkerwell
No Compromises logo

没有妥协

Joel 和 Aaron 是来自 No Compromises 播客的两位经验丰富的开发人员,现在可以为您的 Laravel 项目雇佣他们。 ⬧ 固定费率为 7500 美元/月。 ⬧ 没有冗长的销售流程。 ⬧ 没有合同。 ⬧ 100% 退款保证。

没有妥协
Kirschbaum logo

Kirschbaum

提供创新和稳定性,以确保您的 Web 应用程序取得成功。

Kirschbaum
Shift logo

Shift

正在运行旧版本的 Laravel?即时、自动化的 Laravel 升级和代码现代化,使您的应用程序保持新鲜状态。

Shift
Bacancy logo

Bacancy

只需 2500 美元/月,即可让经验丰富的 Laravel 开发人员(拥有 4-6 年的经验)为您的项目注入活力。获得 160 小时的专业知识和 15 天的无风险试用期。立即安排通话!

Bacancy
Lucky Media logo

Lucky Media

立即获得幸运 - Laravel 开发的理想选择,拥有十多年的经验!

Lucky Media
Lunar: Laravel E-Commerce logo

Lunar:Laravel 电子商务

Laravel 的电子商务。一个开源包,将现代无头电子商务功能的强大功能带到 Laravel。

Lunar:Laravel 电子商务
LaraJobs logo

LaraJobs

官方 Laravel 工作板

LaraJobs
SaaSykit: Laravel SaaS Starter Kit logo

SaaSykit:Laravel SaaS 启动工具包

SaaSykit 是一个 Laravel SaaS 启动工具包,包含运行现代 SaaS 所需的所有功能。支付、精美结账、管理面板、用户仪表板、身份验证、就绪组件、统计信息、博客、文档等。

SaaSykit:Laravel SaaS 启动工具包
Rector logo

Rector

您的合作伙伴,助力无缝 Laravel 升级、降低成本并加快创新,帮助企业取得成功

Rector
MongoDB logo

MongoDB

使用 MongoDB 和 Laravel 的强大集成来增强您的 PHP 应用程序,使开发人员能够轻松高效地构建应用程序。支持事务性、搜索、分析和移动用例,同时使用熟悉的 Eloquent API。了解 MongoDB 的灵活、现代数据库如何改变您的 Laravel 应用程序。

MongoDB
Maska is a Simple Zero-dependency Input Mask Library image

Maska 是一个简单的无依赖项输入掩码库

阅读文章
Add Swagger UI to Your Laravel Application image

将 Swagger UI 添加到您的 Laravel 应用程序

阅读文章
Assert the Exact JSON Structure of a Response in Laravel 11.19 image

在 Laravel 11.19 中断言响应的精确 JSON 结构

阅读文章
Build SSH Apps with PHP and Laravel Prompts image

使用 PHP 和 Laravel Prompts 构建 SSH 应用程序

阅读文章
Building fast, fuzzy site search with Laravel and Typesense image

使用 Laravel 和 Typesense 构建快速模糊的网站搜索

阅读文章
Add Comments to your Laravel Application with the Commenter Package image

使用 Commenter 包将评论添加到您的 Laravel 应用程序

阅读文章