使用自動載入翻譯在 Laravel 中建立多態可翻譯模型

WBOY
發布: 2024-08-11 18:35:32
原創
878 人瀏覽過

Building a Polymorphic Translatable Model in Laravel with Autoloaded Translations

處理多語言內容時,將翻譯儲存在 JSON 欄位中通常比每個屬性的單獨行更有效。這種方法將翻譯整合到單一列中,從而簡化了資料管理和檢索。

設定翻譯系統

我們將增強翻譯模型和表,以使用 JSON 列來儲存翻譯。這將涉及更新表架構並修改 Translatable 特徵以處理 JSON 資料。

第 1 步:建立翻譯表遷移

如果翻譯表尚不存在,請建立一個新的遷移:

php artisan make:migration create_translations_table
登入後複製

第 2 步:定義表結構

在database/migrations中開啟產生的遷移檔案。對於新表,定義如下:

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateTranslationsTable extends Migration
{
    public function up()
    {
        Schema::create('translations', function (Blueprint $table) {
            $table->id();
            $table->string('locale'); // Stores the locale, e.g., 'en', 'fr'
            $table->string('translatable_type'); // Stores the related model type, e.g., 'Post', 'Product'
            $table->unsignedBigInteger('translatable_id'); // Stores the ID of the related model
            $table->json('translations'); // Stores all translations as a JSON object
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('translations');
    }
}
登入後複製

第 3 步:運行遷移
將遷移應用到您的資料庫:

php artisan migrate
登入後複製

第 4 步:建立翻譯模型

接下來,建立翻譯模型來處理多型關係:

php artisan make:model Translation
登入後複製

在翻譯模型中,定義多型關係:

class Translation extends Model
{
    protected $fillable = ['locale', 'translatable_type', 'translatable_id', 'translations'];

    protected $casts = [
        'translations' => 'array',
    ];

    public function translatable()
    {
        return $this->morphTo();
    }
}
登入後複製

使用 JSON 儲存實現可翻譯特徵

為了讓翻譯處理可在多個模型中重複使用,我們將建立一個 Translatable 特徵,它將根據使用者選擇的區域設定自動載入翻譯內容。此外,如果所選語言環境沒有可用的翻譯,我們將新增一個後備機制來從預設語言環境載入內容。

第 1 步:使用 JSON 處理建立可翻譯特徵

namespace App\Traits;

use App\Models\Translation;
use Illuminate\Support\Facades\App;

trait Translatable
{
    public static function bootTranslatable()
    {
        static::retrieved(function ($model) {
            $model->loadTranslations();
        });
    }

    public function translations()
    {
        return $this->morphMany(Translation::class, 'translatable');
    }

    public function loadTranslations()
    {
        $locale = App::getLocale();
        $defaultLocale = config('app.default_locale', 'en'); // Fallback to the default locale

        // Try to load translations for the current locale
        $translation = $this->translations()->where('locale', $locale)->first();

        if (!$translation && $locale !== $defaultLocale) {
            // If no translations are found for the current locale, fallback to the default locale
            $translation = $this->translations()->where('locale', $defaultLocale)->first();
        }

        if ($translation) {
            $translations = $translation->translations;
            foreach ($translations as $key => $value) {
                $this->{$key} = $value;
            }
        }
    }

    public function addTranslations(array $translations, $locale = null)
    {
        $locale = $locale ?? App::getLocale();
        return $this->translations()->updateOrCreate(
            ['locale' => $locale],
            ['translations' => $translations]
        );
    }
}
登入後複製

第 2 步:將可翻譯特徵套用到您的模型
將 Translatable 特徵加入任何需要翻譯支援的模型中。

namespace App\Models;

use App\Traits\Translatable;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use Translatable;

    protected $fillable = ['title', 'content'];
}
登入後複製

範例:建立翻譯模型

將翻譯加入為 JSON 物件:

$post = Post::create(['title' => 'Default Title', 'content' => 'Default Content']);

// Adding translations
$post->addTranslations([
    'title' => 'Hello World',
    'content' => 'Welcome to our website'
], 'en');

$post->addTranslations([
    'title' => 'Bonjour le monde',
    'content' => 'Bienvenue sur notre site Web'
], 'fr');
登入後複製

擷取翻譯模型

當您檢索 Post 模型時,它將根據當前語言環境自動載入翻譯後的內容,或在必要時回退到預設語言環境:

App::setLocale('fr');
$post = Post::find(1);
echo $post->title; // Displays "Bonjour le monde" if French translation exists

App::setLocale('es');
$post = Post::find(1);
echo $post->title; // Displays "Hello World" as it falls back to the English translation
登入後複製

在視圖中顯示翻譯內容

在 Blade 視圖中,您可以像任何其他模型屬性一樣顯示翻譯的內容:

<h1>{{ $post->title }}</h1>
<p>{{ $post->content }}</p>
登入後複製

結論

透過使用 JSON 欄位來儲存翻譯並實作回退機制,您可以簡化 Laravel 應用程式中多語言內容的管理。這種方法將翻譯整合到單一列中,簡化了資料處理並使您的程式碼庫更易於維護。無論您是建立部落格、電子商務網站還是任何多語言應用程序,此方法都能確保流暢高效的用戶體驗。

享受吧!

以上是使用自動載入翻譯在 Laravel 中建立多態可翻譯模型的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板