Maison > Article > développement back-end > Construire un modèle traduisible polymorphe dans Laravel avec des traductions chargées automatiquement
Lors du traitement de contenu multilingue, il est souvent plus efficace de stocker les traductions dans une colonne JSON plutôt que dans des lignes individuelles pour chaque attribut. Cette approche consolide les traductions dans une seule colonne, simplifiant ainsi la gestion et la récupération des données.
Nous améliorerons notre modèle et notre table de traduction pour utiliser une colonne JSON pour stocker les traductions. Cela impliquera de mettre à jour le schéma de la table et de modifier le trait Translatable pour gérer les données JSON.
Étape 1 : Créer une migration de table de traductions
Si la table des traductions n'existe pas déjà, créez une nouvelle migration :
php artisan make:migration create_translations_table
Étape 2 : Définir la structure du tableau
Ouvrez le fichier de migration généré dans base de données/migrations. Pour une nouvelle table, définissez-la comme suit :
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'); } }
Étape 3 : Exécuter la migration
Appliquez la migration à votre base de données :
php artisan migrate
Étape 4 : Créer le modèle de traduction
Ensuite, créez le modèle de traduction pour gérer la relation polymorphe :
php artisan make:model Translation
Dans le modèle Translation, définissez la relation polymorphe :
class Translation extends Model { protected $fillable = ['locale', 'translatable_type', 'translatable_id', 'translations']; protected $casts = [ 'translations' => 'array', ]; public function translatable() { return $this->morphTo(); } }
Pour rendre la gestion des traductions réutilisable sur plusieurs modèles, nous allons créer un trait Traductible qui chargera automatiquement le contenu traduit en fonction des paramètres régionaux sélectionnés par l'utilisateur. De plus, nous ajouterons un mécanisme de secours pour charger le contenu à partir des paramètres régionaux par défaut si aucune traduction n'est disponible pour les paramètres régionaux sélectionnés.
Étape 1 : Créer le trait traduisible avec la gestion 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] ); } }
Étape 2 : appliquez le trait traduisible à votre modèle
Ajoutez le trait Traductible à tout modèle nécessitant une prise en charge de la traduction.
namespace App\Models; use App\Traits\Translatable; use Illuminate\Database\Eloquent\Model; class Post extends Model { use Translatable; protected $fillable = ['title', 'content']; }
Ajouter des traductions en tant qu'objet 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');
Récupération de modèles traduits
Lorsque vous récupérez le modèle Post, il chargera automatiquement le contenu traduit en fonction des paramètres régionaux actuels ou reviendra aux paramètres régionaux par défaut si nécessaire :
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
Affichage du contenu traduit dans les vues
Dans vos vues Blade, vous pouvez afficher le contenu traduit comme n'importe quel autre attribut de modèle :
<h1>{{ $post->title }}</h1> <p>{{ $post->content }}</p>
Conclusion
En utilisant une colonne JSON pour stocker les traductions et en mettant en œuvre un mécanisme de secours, vous rationalisez la gestion du contenu multilingue dans votre application Laravel. Cette approche consolide les traductions dans une seule colonne, simplifiant ainsi la gestion des données et rendant votre base de code plus maintenable. Que vous construisiez un blog, un site de commerce électronique ou toute autre application multilingue, cette méthode garantit une expérience utilisateur fluide et efficace.
Profitez !
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!