novius/laravel-filament-translatable
Adds translation support to Filament in Laravel, helping you manage translatable Eloquent models and localized form fields/resources from one admin panel. Lightweight package to streamline multilingual CRUD for Filament apps.
Installation
composer require novius/laravel-filament-translatable
Publish the package config (if needed):
php artisan vendor:publish --provider="Novius\FilamentTranslatable\FilamentTranslatableServiceProvider"
Enable Translatable Fields Add the trait to your Filament resource model:
use Novius\FilamentTranslatable\Traits\Translatable;
class Post extends Model
{
use Translatable;
}
Define Translatable Fields
In your Filament resource, use the translatable() method:
public static function form(Form $form): Form
{
return $form
->schema([
TextInput::make('title')
->translatable(),
RichEditor::make('content')
->translatable(),
]);
}
First Use Case
Post).title in English and French).Field Configuration
Use translatable() on Filament fields to enable translations:
TextInput::make('description')
->translatable()
->columnSpanFull()
->required();
Locale Selection Dynamically set the current locale in the form:
public static function form(Form $form): Form
{
return $form
->schema([
Select::make('locale')
->options(['en', 'fr', 'es'])
->default('en'),
// Translatable fields...
]);
}
Table Integration Display translations in the table:
public static function table(Table $table): Table
{
return $table
->columns([
TextColumn::make('title')
->translatable(),
]);
}
Bulk Actions
Use translatable() with bulk actions (e.g., edit, delete) to ensure translations are preserved:
public static function getBulkActions(): array
{
return [
Tables\Actions\DeleteBulkAction::make()
->requiresConfirmation(),
];
}
app()->setLocale() to enforce locale-specific views.public function toArray()
{
return [
'title' => $this->getTranslation('title', app()->getLocale()),
];
}
$this->validate([
'title_en' => 'required|string|max:255',
'title_fr' => 'required|string|max:255',
]);
Missing Locale Fallback
null. Configure a fallback:
$post->getTranslation('title', 'en'); // Fallback to English
Database Schema Mismatch
title_en, title_fr). Run migrations if needed:
php artisan migrate
Caching Issues
php artisan filament:cache:clear
php artisan optimize:clear
Field Overrides
translatable():
// ❌ Broken
TextInput::make('title')->required();
// ✅ Fixed
TextInput::make('title')->translatable()->required();
dd($model->getTranslations());
config(['filament-translatable.debug' => true]);
Custom Storage Override the default storage (e.g., JSON column):
use Novius\FilamentTranslatable\Contracts\TranslatableStorage;
class CustomStorage implements TranslatableStorage
{
public function store($model, $field, $locale, $value)
{
// Custom logic
}
}
// Register in config/filament-translatable.php
Dynamic Locales Fetch locales dynamically (e.g., from a config file):
$locales = config('app.available_locales');
Localization Hooks Use Filament’s hooks to modify translations:
Filament::serving(function () {
Filament::registerFormModification(
PostResource::class,
fn (Form $form) => $form->schema([
// Modify translatable fields here
])
);
});
Testing Test translations with Pest:
it('saves translations', function () {
$post = Post::create(['title_en' => 'Hello']);
expect($post->getTranslation('title', 'en'))->toBe('Hello');
});
How can I help you explore Laravel packages today?