Guide : Rendre un Modèle Traduisible
Version : 1.0 Date : 2026-01-25 Story : Epic 5, Story 5.4
Vue d'ensemble
Ce guide explique comment rendre un modèle Eloquent traduisible en utilisant le système de traduction multilingue. En suivant ces étapes, vous pourrez stocker et récupérer des traductions pour les champs de votre modèle.
1. Prérequis
- Les traductions doivent être activées :
TRANSLATIONS_ENABLED=true - Le composant BDD doit être activé :
TRANSLATIONS_DATABASE_ENABLED=true - Le package
spatie/laravel-translatabledoit être installé
2. Étapes de migration
Étape 1 : Créer la migration
Créez une migration pour modifier les colonnes en JSON :
php artisan make:migration make_{table}_translatable --table={table}
Exemple : Pour la table articles
<?phpuse Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::table('articles', function (Blueprint $table) {
// Modifier les colonnes en JSON
$table->json('title')->nullable()->change();
$table->json('content')->nullable()->change();
$table->json('slug')->nullable()->change();
});
}
public function down(): void
{
Schema::table('articles', function (Blueprint $table) {
// Revenir en string (perte de données)
$table->string('title')->nullable()->change();
$table->text('content')->nullable()->change();
$table->string('slug')->nullable()->change();
});
}
};
Étape 2 : Ajouter le trait au modèle
<?phpnamespace App\Models;
use App\Specifics\Shares\Models\Concerns\ConditionallyTranslatable;
use Illuminate\Database\Eloquent\Model;
class Article extends Model
{
use ConditionallyTranslatable;
protected $fillable = [
'title',
'content',
'slug',
];
protected function getTranslatableFields(): array
{
return ['title', 'content', 'slug'];
}
}
Étape 3 : Configurer les casts (optionnel)
Si vous voulez que Laravel gère automatiquement le cast JSON :
protected function casts(): array
{
return [
'title' => 'array',
'content' => 'array',
'slug' => 'array',
];
}
Note : Le trait ConditionallyTranslatable gère automatiquement les casts selon l'activation des traductions.
Étape 4 : Activer pour le modèle
Fichier : .env
TRANSLATIONS_MODEL_ARTICLE=true
Ou dans config/translations.php :
'models' => [
'article' => env('TRANSLATIONS_MODEL_ARTICLE', true),
],
3. Migration des données existantes
Si vous avez déjà des données dans la table, vous devez les migrer vers le format JSON.
Option 1 : Utiliser la commande de migration
php artisan translate:migrate-data --model=Article
Option 2 : Migration manuelle
use App\Models\Article;$articles = Article::all();
$defaultLocale = config('translations.default_locale', 'fr');
foreach ($articles as $article) {
// Récupérer l'ancienne valeur (string)
$oldTitle = $article->getRawOriginal('title');
$oldContent = $article->getRawOriginal('content');
$oldSlug = $article->getRawOriginal('slug');
// Convertir en JSON pour la locale par défaut
if ($oldTitle) {
$article->setTranslation('title', $defaultLocale, $oldTitle);
}
if ($oldContent) {
$article->setTranslation('content', $defaultLocale, $oldContent);
}
if ($oldSlug) {
$article->setTranslation('slug', $defaultLocale, $oldSlug);
}
$article->save();
}
4. Utilisation
Créer avec traductions
$article = new Article();
$article->setTranslation('title', 'fr', 'Mon article');
$article->setTranslation('title', 'es', 'Mi artículo');
$article->setTranslation('content', 'fr', 'Contenu en français');
$article->setTranslation('content', 'es', 'Contenido en español');
$article->save();
Récupérer les traductions
// Selon la locale courante
$title = $article->title; // Retourne selon app()->getLocale()// Explicitement
$titleFr = $article->getTranslation('title', 'fr');
$titleEs = $article->getTranslation('title', 'es');
// Avec helper
$title = trans_model($article, 'title');
Mettre à jour les traductions
$article->setTranslation('title', 'fr', 'Nouveau titre');
$article->save();
Récupérer toutes les traductions
$allTranslations = $article->getTranslations('title');
// ['fr' => 'Mon article', 'es' => 'Mi artículo']
5. Utilisation dans Filament
Voir le Guide Filament pour les détails complets.
Résumé :
use App\Filament\Support\TranslatableField;...TranslatableField::makeTextInput('title', 'Titre',
fn ($field) => $field->required()
),
6. Exemple complet
Modèle
<?phpnamespace App\Models;
use App\Specifics\Shares\Models\Concerns\ConditionallyTranslatable;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
use ConditionallyTranslatable;
protected $fillable = [
'name',
'description',
'slug',
'price',
];
protected function getTranslatableFields(): array
{
return ['name', 'description', 'slug'];
}
}
Migration
Schema::table('products', function (Blueprint $table) {
$table->json('name')->nullable()->change();
$table->json('description')->nullable()->change();
$table->json('slug')->nullable()->change();
// 'price' reste decimal (non traduisible)
});
Utilisation
$product = Product::create([
'price' => 29.99,
]);$product->setTranslation('name', 'fr', 'Produit français');
$product->setTranslation('name', 'es', 'Producto español');
$product->setTranslation('description', 'fr', 'Description en français');
$product->setTranslation('description', 'es', 'Descripción en español');
$product->save();
// Récupérer
app()->setLocale('fr');
$name = $product->name; // "Produit français"
app()->setLocale('es');
$name = $product->name; // "Producto español"
7. Checklist
ConditionallyTranslatable ajouté au modèlegetTranslatableFields() implémentée.env : TRANSLATIONS_MODEL_{MODEL}=true8. Bonnes pratiques
article, pas Article)9. Dépannage
Les traductions ne sont pas sauvegardées
TRANSLATIONS_ENABLED=trueTRANSLATIONS_DATABASE_ENABLED=trueTRANSLATIONS_MODEL_{MODEL}=trueErreur "Call to undefined method getTranslation()"
ConditionallyTranslatable est utiliségetTranslatableFields() retourne un tableau non videProchaines étapes : Consultez le Guide de Traduction BDD pour plus de détails.