Guide : Traductions dans Filament v5
Problème
Le plugin officiel filament/spatie-laravel-translatable-plugin n'est pas compatible avec Filament v5 (seulement v3).
Solution
Une solution personnalisée a été créée pour gérer les traductions dans Filament v5 en utilisant spatie/laravel-translatable.
Utilisation
Helper TranslatableField
Un helper TranslatableField a été créé dans app/Filament/Support/TranslatableField.php pour faciliter la création de champs traduisibles dans les formulaires Filament.
Exemple d'utilisation
use App\Filament\Support\TranslatableField;
use Filament\Schemas\Schema;class ProductForm
{
public static function configure(Schema $schema): Schema
{
return $schema
->components([
// Champ texte traduisible
TranslatableField::makeTextInput('name', 'Nom du produit'),
// Champ textarea traduisible
TranslatableField::makeTextarea('description', 'Description'),
// Autres champs non traduisibles
TextInput::make('price')
->label('Prix')
->numeric(),
]);
}
}
Fonctionnement
TRANSLATIONS_FILAMENT_ENABLED=true) :Configuration
Assurez-vous que la configuration suivante est activée dans .env :
TRANSLATIONS_ENABLED=true
TRANSLATIONS_FILAMENT_ENABLED=true
TRANSLATIONS_DATABASE_ENABLED=true
Sauvegarde des données
Les données sont sauvegardées au format JSON dans la base de données, comme défini par spatie/laravel-translatable :
{
"fr": "Nom en français",
"es": "Nombre en español"
}
Modèles
Les modèles doivent utiliser le trait ConditionallyTranslatable :
use App\Specifics\Shares\Models\Concerns\ConditionallyTranslatable;class Product extends Model
{
use ConditionallyTranslatable;
protected function getTranslatableFields(): array
{
return ['name', 'description'];
}
}
Architecture simplifiée pour composants Livewire imbriqués
Pour les pages Filament qui utilisent des composants Livewire imbriqués (comme EditPost ou CreatePost), une architecture simplifiée a été mise en place avec un array $translations pour stocker toutes les traductions.
Principe
Au lieu de gérer les traductions via des événements complexes et allFormData, chaque composant Livewire imbriqué maintient un array $translations qui stocke toutes les traductions par locale :
public array $translations = [
'fr' => ['title' => '...', 'slug' => '...', 'excerpt' => '...', 'content' => '...'],
'es' => ['title' => '...', 'slug' => '...', 'excerpt' => '...', 'content' => '...'],
];
Méthodes clés
loadAllTranslations() : Charge toutes les traductions depuis la BDD au mountdisplayCurrentLocale() : Affiche les valeurs de la locale courante dans les champssaveCurrentLocaleToTranslations() : Sauvegarde les valeurs actuelles dans $translationssaveAllTranslations() : Sauvegarde toutes les traductions dans la BDDonLocaleChanged(string $locale) : Gère le changement de locale (sauvegarde → change → affiche)Avantages
- Simplicité : Pas de communication asynchrone entre composants
- Isolation : Chaque locale a son propre espace dans
$translations - Fiabilité : Pas de copie accidentelle entre locales
- Performance : Chargement unique de toutes les traductions au mount
- Maintenabilité : Code beaucoup plus simple et lisible
- Cette solution ne fournit pas toutes les fonctionnalités du plugin officiel
- Le sélecteur de langue est basique (peut être amélioré)
- Les champs sont organisés dans des Sections (peut être personnalisé)
- Créer un composant Filament personnalisé plus avancé
- Ajouter un sélecteur de langue plus élégant
- Améliorer l'UX pour la gestion des traductions
Exemple complet
Voir la section "Architecture simplifiée pour composants Livewire imbriqués" dans la documentation complète (/docs/translation).