如何在 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 的包自述文件中的示例。仍然渴望获得更多知识?深入研究他在 GitHub 上的包代码。它并不难理解,您可以从中学到很多东西。

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 提示构建 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 应用程序添加评论

阅读文章