indigoram89/laravel-translatable

一个特质,使 Eloquent 模型能够存储翻译

4.5.2 2020-10-22 13:52 UTC

README

Latest Version on Packagist MIT Licensed GitHub Workflow Status Total Downloads

此包包含一个特质,使 Eloquent 模型可翻译。翻译存储为 json 格式。不需要额外的表来存储它们。

一旦特质安装到模型上,您可以执行以下操作

$newsItem = new NewsItem; // This is an Eloquent model
$newsItem
   ->setTranslation('name', 'en', 'Name in English')
   ->setTranslation('name', 'nl', 'Naam in het Nederlands')
   ->save();
   
$newsItem->name; // Returns 'Name in English' given that the current app locale is 'en'
$newsItem->getTranslation('name', 'nl'); // returns 'Naam in het Nederlands'

app()->setLocale('nl');

$newsItem->name; // Returns 'Naam in het Nederlands'

支持我们

我们投入了大量资源来创建一流的开放式软件包。您可以通过购买我们的付费产品之一来支持我们。

我们非常感谢您从您的家乡寄给我们明信片,注明您正在使用我们哪个包。您可以在我们的联系页面上找到我们的地址。我们将所有收到的明信片发布在我们的虚拟明信片墙上

安装

您可以通过 composer 安装此包

composer require spatie/laravel-translatable

如果您想要使用另一个 fallback_locale 而不是应用程序的 fallback locale(见 config/app.php),您可以发布配置文件

php artisan vendor:publish --provider="Spatie\Translatable\TranslatableServiceProvider"

这是已发布文件的 contents

return [
  'fallback_locale' => 'en',
];

制作可翻译的模型

使模型可翻译所需的步骤

  • 首先,您需要添加 Spatie\Translatable\HasTranslations-trait。
  • 接下来,您应该创建一个公共属性 $translatable,它包含所有希望使其可翻译的属性名称的数组。
  • 最后,您应该确保所有可翻译的属性都设置为您数据库中的 text 数据类型。如果您的数据库支持 json 列,则使用该列。

以下是一个准备好的模型示例

use Illuminate\Database\Eloquent\Model;
use Spatie\Translatable\HasTranslations;

class NewsItem extends Model
{
    use HasTranslations;
    
    public $translatable = ['name'];
}

可用方法

获取翻译

获取当前区域设置的翻译的最简单方法是直接获取翻译属性的性质。例如(假设 name 是一个可翻译属性)

$newsItem->name;

您也可以使用此方法

public function getTranslation(string $attributeName, string $locale, bool $useFallbackLocale = true) : string

此函数有一个名为 translate 的别名。

获取所有翻译

您可以通过调用 getTranslations() 而不带参数来获取所有翻译

$newsItem->getTranslations();

或者您可以使用访问器

$yourModel->translations

设置翻译

设置当前区域设置的翻译的最简单方法是直接设置可翻译属性的性质。例如(假设 name 是一个可翻译属性)

$newsItem->name = 'New translation';

您还可以使用以下方式设置翻译

$newItem->name = ['en' => 'myName', 'nl' => 'Naam in het Nederlands'];

要为特定区域设置设置翻译,您可以使用此方法

public function setTranslation(string $attributeName, string $locale, string $value)

要实际保存翻译,请记住保存您的模型。

$newsItem->setTranslation('name', 'en', 'Updated name in English');

$newsItem->save();

验证

  • 如果您想在保存/更新数据库之前对属性进行唯一性验证,您可能需要查看 laravel-unique-translation,它专门为 laravel-translatable 制作。

忘记翻译

您可以为特定字段忘记翻译

public function forgetTranslation(string $attributeName, string $locale)

您可以为特定区域设置忘记所有翻译

public function forgetAllTranslations(string $locale)

一次性获取所有翻译

public function getTranslations(string $attributeName): array

一次性设置翻译

public function setTranslations(string $attributeName, array $translations)

以下是一个示例

$translations = [
   'en' => 'Name in English',
   'nl' => 'Naam in het Nederlands'
];

$newsItem->setTranslations('name', $translations);

一次性替换翻译

您可以使用此方法替换单个键的所有翻译

public function replaceTranslations(string $key, array $translations)

以下是一个示例

$translations = ['en' => 'hello', 'es' => 'hola'];

$newsItem->setTranslations('hello', $translations);
$newsItem->getTranslations(); // ['en' => 'hello', 'es' => 'hola']

$newTranslations = ['en' => 'hello'];

$newsItem->replaceTranslations('hello', $newTranslations);
$newsItem->getTranslations(); // ['en' => 'hello']

设置模型区域

用于翻译模型的默认区域设置为应用程序区域,但是有时使用自定义区域可能很方便。

要这样做,您可以在模型实例上使用 setLocale

$newsItem = NewsItem::firstOrFail()->setLocale('fr');

// Any properties on this model will automaticly be translated in French
$newsItem->name; // Will return `fr` translation
$newsItem->name = 'Actualité'; // Will set the `fr` translation

或者,您可以使用 usingLocale 静态方法。

// Will automatically set the `fr` translation
$newsItem = NewsItem::usingLocale('fr')->create([
    'name' => 'Actualité',
]);

事件

TranslationHasBeenSet

在调用 setTranslation 后,将触发 Spatie\Translatable\Events\TranslationHasBeenSet 事件。

它具有以下属性

/** @var \Illuminate\Database\Eloquent\Model */
public $model;

/** @var string  */
public $attributeName;

/** @var string  */
public $locale;

public $oldValue;
public $newValue;

创建模型

在创建模型时可以立即设置翻译。以下是一个示例

NewsItem::create([
   'name' => [
      'en' => 'Name in English',
      'nl' => 'Naam in het Nederlands'
   ],
]);

查询可翻译属性

如果您正在使用 MySQL 5.7 或更高版本,建议您在数据库中存储翻译时使用 json 数据类型。这将允许您像这样查询这些列

NewsItem::where('name->en', 'Name in English')->get();

或者如果您正在使用 MariaDB 10.2.3 或更高版本

NewsItem::whereRaw("JSON_EXTRACT(name, '$.en') = 'Name in English'")->get();

更新日志

请参阅 更新日志 了解最近有哪些变化。

升级

从 v2 升级到 v3

在大多数情况下,您可以升级而不必对代码库进行任何更改。v3 为您的模型引入了 translations 访问器。如果您已经在模型上定义了一个,您需要将其重命名。

测试

composer test

贡献

请参阅 贡献指南 了解详细信息。

安全

如果您发现任何安全问题,请通过电子邮件 freek@spatie.be 反馈,而不是使用问题跟踪器。

明信片软件

您可以使用这个包,但如果它进入您的生产环境,我们非常希望您能从家乡寄给我们一张明信片,提到您正在使用我们哪个包。

我们的地址是:Spatie,Kruikstraat 22,2018 安特卫普,比利时。

我们将所有收到的明信片 发布在我们的公司网站上

致谢

我们从 Mohamed Said 那里得到了将翻译存储为 json 的想法,在列中。此说明书的某些部分使用了他的多语言包的说明。

许可证

MIT 许可证(MIT)。有关更多信息,请参阅 许可证文件