msafadi/laravel-eloquent-l10n

Laravel Eloquent 本地化

v1.0.1 2024-05-24 19:23 UTC

This package is auto-updated.

Last update: 2024-09-24 20:17:58 UTC


README

在当今全球化的世界中,跨越国界触及受众比以往任何时候都更加重要。为了有效地吸引来自不同背景的用户,提供他们母语的内容至关重要。然而,管理内容翻译可能是一个复杂且耗时的过程。

这就是 Laravel Eloquent 本地化和翻译包发挥作用的地方。它提供了一种全面且易于使用的解决方案,以简化您的内容翻译工作流程。

传统翻译管理的挑战

  • 手动过程:在不同的页面和模型之间手动翻译内容可能既繁琐又容易出错。
  • 格式不一致:在整个翻译内容中保持一致的格式和样式可能是一个重大的挑战。
  • 可扩展性有限:随着您的网站增长并添加更多语言,管理翻译可能变得越来越困难。

功能

Laravel Eloquent 本地化和翻译包使您能够

  • 轻松集成翻译:通过最少的代码将翻译功能集成到您的 Eloquent 模型中。
  • 选择您的存储方法:选择最适合您项目的方法 - 专门翻译表以实现结构化方法或存储在模型属性中的简单场景。
  • 自动翻译加载:在检索模型时享受自动预加载翻译的性能优势。
  • 轻松访问翻译属性:通过方便的方法直接在您的模型实例上访问翻译内容。
  • Artisan 命令提高效率:利用 artisan 命令生成翻译表迁移的起点,节省您的时间。

通过提供灵活且易于使用的解决方案,此包帮助您有效地管理内容翻译,确保您的全球受众获得无缝体验。此 Laravel 包使您能够轻松管理 Eloquent 模型的翻译。它提供了两种灵活的方法

  1. 专用翻译表:这种结构化方法允许每个模型都有自己的翻译表,可能包括针对特定需求的额外列。
  2. 模型属性:对于简单场景,可以将翻译直接作为 JSON 存储在模型的属性中,提供一种轻量级解决方案。

安装

  1. 使用 Composer 安装包

    composer require msafadi/laravel-eloquent-l10n
  2. 可选地,您可以发布配置文件以进行自定义

    php artisan vendor:publish --provider="Safadi\Eloquent\L10n\EloquentL10nServiceProvider"
  3. 将包的提供者类 EloquentL10nServiceProvider 添加到应用程序的提供者数组中

    • Laravel 11.x
    <?php
    // Laravel v11.x
    // file: bootstrap/app.php
    
    use Illuminate\Foundation\Application;
    use Illuminate\Foundation\Configuration\Exceptions;
    use Illuminate\Foundation\Configuration\Middleware;
    use Safadi\Eloquent\L10n\EloquentL10nServiceProvider;
    
    return Application::configure(basePath: dirname(__DIR__))
        ->withRouting(
            web: __DIR__.'/../routes/web.php',
            api: __DIR__.'/../routes/api.php',
            commands: __DIR__.'/../routes/console.php',
            health: '/up',
        )
        // ...
        ->withProviders([
            // ...
            EloquentL10nServiceProvider::class
        ])
        ->create();
    • Laravel 10.x 及更早版本
    <?php
    // Laravel 10.x and older
    // file: config/app.php
    
    'providers' => ServiceProvider::defaultProviders()->merge([
        /*
         * Package Service Providers...
         */
        EloquentL10nServiceProvider::class
    
        /*
         * Application Service Providers...
         */
        App\Providers\AppServiceProvider::class,
        // ...
    
    ])->toArray(),

配置

包配置文件(config/eloquent-l10n.php)提供了选项,以便根据您项目的具体需求调整包

  • 默认翻译模型:如果您使用专用翻译表方法,指定用于翻译的模型类(可以保留为包提供的默认类)。
  • 自定义选项
    • 翻译表后缀:覆盖默认翻译表名称后缀(_l10n)。
    • 区域设置列:更改存储区域标识符的默认列名(locale)。
    • 翻译模型:自定义翻译模型(Safadi\Eloquent\L10n\L10n)。

用法

1. 专用翻译表

1.1. 模型设置

  • HasTranslationsModel 特性纳入您的模型类。
  • 验证您的模型实现了 Safadi\Eloquent\L10n\Contracts\Translatable 协议。
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Safadi\Eloquent\L10n\Concerns\HasTranslationsModel;
use Safadi\Eloquent\L10n\Contracts\Translatable;

class Post extends Model implements Translatable
{
    use HasTranslationsModel;
}

1.2. 使用方法

  • 此包提供了一个动态的 Translation 模型,可用于所有翻译表。
  • 使用 attribute_name 访问翻译属性,指定所需的区域和属性名称
<?php

// Use the current application locale
$post = Post::find(1);
$translatedTitle = $post->title;

// Specify the locale manually
$post = Post::useLocale('ar')->find(1);
$translatedTitle = $post->title;

此包将执行与相关翻译表的左连接,并使用指定的 locale 代码进行约束。这允许像访问单个表一样访问和调用可翻译属性。

1.3. 创建和保存翻译

该包通过在翻译表上执行 upsert 操作,提供了保存模型翻译的便捷方式。如果指定区域不存在现有翻译,则将其插入,否则更新。

<?php
$post->setLocale('ar')->translate([
    'title' => 'Post Title Updated',
    'content' => 'Post content',
]);

// or
$post->translate([
    'title' => 'Post Title Updated',
    'content' => 'Post content',
], 'ar');

//
$post = Post::withTranslations([
    'en' => [
        'title' => 'Post Title',
        'content' => 'Post content',
        // ...
    ],
    'ar' => [
        'title' => 'عنوان المنشور',
        'content' => 'محتوى المنشور',
        // ...
    ],
    // ...
])->create([
    'status' => 'published',
    // ...
    // Non translatable post attributes
]);

1.4. 翻译关系

该包还定义了名为 translationsHasMany 关系。

<?php

echo Post::find(1)->translations()->count();

foreach (Post::find(1)->translations as $translation) {
    echo $translation->locale;
    echo $translation->title;
    // ...
}

您还可以通过调用 withoutTranslations 来停止全局作用域的默认行为,该作用域在模型表和其翻译表之间执行连接。

<?php

$posts = Post::withoutTranslations()->get();

echo Post::withoutTranslations()->count();

1.5. 自定义(可选)

  • 如果您更喜欢创建自定义翻译模型类,您可以在模型中使用 hasMany 方法定义与翻译表的关联。

1.6. Artisan 命令

使用 artisan 命令来生成翻译表的迁移起点

php artisan make:l10n-table MyModel

将 MyModel 替换为您实际的模型类名或表名。

2. 模型属性

2.1. 模型设置

  • 在您的模型类中包含 HasTranslatableAttributes 特性。
  • 验证您的模型实现了 Safadi\Eloquent\L10n\Contracts\Translatable 协议。
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Safadi\Eloquent\L10n\Concerns\\HasTranslatableAttributes;
use Safadi\Eloquent\L10n\Contracts\Translatable;

class Post extends Model implements Translatable
{
    use HasTranslatableAttributes;

    public function translatableAttributes(): array
    {
        return ['title', 'content']; // Specify translatable attributes
    }
}

2.2. 使用方法

  • 该包将翻译存储在 translations 属性中的 JSON 格式内,遵循以下格式
{
    "en": {
        "title": "English Title",
        "content": "English Content"
    },
    "fr": {
        "title": "Titre Français",
        "content": "Contenu Français"
    }
}
  • 使用 attribute 名称正常访问翻译属性
$post = Post::find(1);

// Get title translated with the current application locale
$translatedTitle = $post->title;

// Get title translated with the specified locale
$translatedTitle = $post->setLocale('ar')->title;

2.3. 保存翻译

$post = Post::create([
    'status' => 'published',
    'author' => 'Mohammed',
    // ...,
    'title' => [
        'en' => 'Post Title',
        'ar' => 'عنوان المنشور',
        // ...
    ],
    'content' => [
        'en' => 'Post content',
        'ar' => 'محتوى المنشور',
        // ...
    ],
]);

//
$post = new Post();
// Set all translations at once
$post->title = [
    'en' => 'Post Title',
    'ar' => 'عنوان المنشور',
    // ...
];
$post->save();

// Update partial translations
$post = Post::find(1);

// Update title in the current application locale, keep other translations without change.
$post->title = 'English';

// Specify the translation locale.
// This will update the `ar` translation and keep other translations without change.
$post->setLocale('ar')->content = 'عربي';
// ...
$post->save();

贡献

我们重视对该包的贡献!请参阅贡献指南以获取详细信息。

许可

此包在 MIT 许可下开源。