jeffersongoncalves / filament-translatable
Enhanced Filament plugin for spatie/laravel-translatable with translation status indicators, locale flags, and improved DX.
Installs: 0
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 0
Forks: 0
pkg:composer/jeffersongoncalves/filament-translatable
Requires
- php: ^8.2
- filament/filament: ^5.0
- spatie/laravel-package-tools: ^1.14.0
- spatie/laravel-translatable: ^6.0
Requires (Dev)
- larastan/larastan: ^2.0
- laravel/pint: ^1.0
- orchestra/testbench: ^9.0|^10.0|^11.0
- pestphp/pest: ^2.0
- pestphp/pest-plugin-laravel: ^2.0
README
Filament Translatable
Enhanced Filament plugin for spatie/laravel-translatable with translation status indicators, locale flags, and improved developer experience.
Version Compatibility
| Branch | Filament | PHP | Laravel | Tailwind | Livewire | Install |
|---|---|---|---|---|---|---|
| 1.x | v3 | ^8.1 | 10+ | 3.x | 3.x | "^1.0" |
| 2.x | v4 | ^8.2 | 11+ | 4.x | 3.x | "^2.0" |
| 3.x | v5 | ^8.2 | 11.28+ | 4.x | 4.x | "^3.0" |
You are viewing the documentation for branch 3.x (Filament v5).
Features
- Locale Switching - Switch between locales on Create, Edit, List, View, and Manage pages
- Translation Status Column - Visual table column showing translation completeness per locale with colored badges
- Translation Status Trait - Introspect translation status (complete/partial/empty) and completeness percentage
- Locale Flags - Emoji flag support with configurable display (flag+label, flag only, label only)
- Unified DX Trait -
InteractsWithTranslationsfor less boilerplate - SQLite Search - JSON search support for SQLite (in addition to MySQL and PostgreSQL)
- RelationManager Support - Independent locale management for relation managers
- 30+ Built-in Flags - Pre-configured emoji flags for the most common locales
Installation
composer require jeffersongoncalves/filament-translatable:"^3.0"
Optionally publish the config:
php artisan vendor:publish --tag="filament-translatable-config"
Setup
1. Configure your Model
Your model must use Spatie's HasTranslations trait:
use Illuminate\Database\Eloquent\Model; use Spatie\Translatable\HasTranslations; class Post extends Model { use HasTranslations; protected $fillable = ['title', 'content', 'slug']; public array $translatable = ['title', 'content']; }
Translatable columns must use json type in your migration:
Schema::create('posts', function (Blueprint $table) { $table->id(); $table->json('title'); $table->json('content'); $table->string('slug'); // non-translatable fields use regular column types $table->timestamps(); });
2. Register the Plugin
Add the plugin to your PanelProvider:
use JeffersonGoncalves\FilamentTranslatable\FilamentTranslatablePlugin; public function panel(Panel $panel): Panel { return $panel ->plugins([ FilamentTranslatablePlugin::make() ->defaultLocales(['en', 'pt_BR', 'es']), ]); }
3. Add Translatable to your Resource
use JeffersonGoncalves\FilamentTranslatable\Resources\Concerns\Translatable; class PostResource extends Resource { use Translatable; // ... }
4. Add Translatable to Pages
Each page type needs its own trait and the LocaleSwitcher header action:
use JeffersonGoncalves\FilamentTranslatable\Actions\LocaleSwitcher; use JeffersonGoncalves\FilamentTranslatable\Resources\Pages\CreateRecord; use JeffersonGoncalves\FilamentTranslatable\Resources\Pages\EditRecord; use JeffersonGoncalves\FilamentTranslatable\Resources\Pages\ListRecords; class CreatePost extends CreateRecord { use CreateRecord\Concerns\Translatable; protected function getHeaderActions(): array { return [LocaleSwitcher::make()]; } } class EditPost extends EditRecord { use EditRecord\Concerns\Translatable; protected function getHeaderActions(): array { return [LocaleSwitcher::make()]; } } class ListPosts extends ListRecords { use ListRecords\Concerns\Translatable; protected function getHeaderActions(): array { return [LocaleSwitcher::make()]; } }
Additional page types are also supported:
use JeffersonGoncalves\FilamentTranslatable\Resources\Pages\ViewRecord; use JeffersonGoncalves\FilamentTranslatable\Resources\Pages\ManageRecords; // ViewRecord class ViewPost extends ViewRecord { use ViewRecord\Concerns\Translatable; protected function getHeaderActions(): array { return [LocaleSwitcher::make()]; } } // ManageRecords (simple resource) class ManagePosts extends ManageRecords { use ManageRecords\Concerns\Translatable; protected function getHeaderActions(): array { return [LocaleSwitcher::make()]; } }
Translation Status Column
Show translation completeness per locale in your table with colored badges:
use JeffersonGoncalves\FilamentTranslatable\Tables\Columns\TranslationStatusColumn; public static function table(Table $table): Table { return $table->columns([ TextColumn::make('title'), TranslationStatusColumn::make('translations') ->showPercentage() // show completion percentage ->onlyShowMissing() // hide locales that are fully translated ->showFlags() // show emoji flags next to locale labels ->locales(['en', 'pt_BR', 'es']), // override plugin locales ]); }
Each locale displays a colored badge indicating its translation status:
- Success (green) - All translatable attributes are filled
- Warning (yellow) - Some translatable attributes are filled
- Danger (red) - No translatable attributes are filled
Translation Status Trait
Use HasTranslationStatus on any page to check translation status programmatically:
use JeffersonGoncalves\FilamentTranslatable\Concerns\HasTranslationStatus; class EditPost extends EditRecord { use EditRecord\Concerns\Translatable; use HasTranslationStatus; }
Available methods:
// Get status per locale: 'complete', 'partial', or 'empty' $this->getTranslationStatus($record); // => ['en' => 'complete', 'pt_BR' => 'partial', 'fr' => 'empty'] // Get completeness percentage per locale (0-100) $this->getTranslationCompleteness($record); // => ['en' => 100, 'pt_BR' => 50, 'fr' => 0] // Get locales that have at least one translated attribute $this->getTranslatedLocales($record); // => ['en', 'pt_BR']
Locale Flags
The plugin ships with 30+ built-in emoji flags. Configure them per locale in the plugin or via config:
FilamentTranslatablePlugin::make() ->defaultLocales(['en', 'pt_BR', 'es']) ->localeFlags([ 'en' => "\u{1F1FA}\u{1F1F8}", 'pt_BR' => "\u{1F1E7}\u{1F1F7}", 'es' => "\u{1F1EA}\u{1F1F8}", ]) ->flagDisplay('flag_and_label'), // 'flag_and_label' | 'flag_only' | 'label_only'
Built-in flags include: en, pt_BR, pt, es, fr, de, it, nl, ja, ko, zh, ru, ar, hi, tr, pl, uk, sv, da, no, fi, cs, el, ro, hu, th, vi, id, ms, he.
Custom Locale Labels
Override how locale names are displayed:
FilamentTranslatablePlugin::make() ->defaultLocales(['en', 'pt_BR']) ->getLocaleLabelUsing(fn (string $locale) => match ($locale) { 'en' => 'English', 'pt_BR' => 'Portugues', default => null, // falls back to locale_get_display_name() }),
RelationManager
Relation managers have independent locale management using a dedicated LocaleSwitcher:
use JeffersonGoncalves\FilamentTranslatable\Resources\RelationManagers\Concerns\Translatable; use JeffersonGoncalves\FilamentTranslatable\Tables\Actions\LocaleSwitcher; class CommentsRelationManager extends RelationManager { use Translatable; protected function getHeaderActions(): array { return [LocaleSwitcher::make()]; } }
Note: Relation managers use
JeffersonGoncalves\FilamentTranslatable\Tables\Actions\LocaleSwitcher(fromTables\Actions), while pages useJeffersonGoncalves\FilamentTranslatable\Actions\LocaleSwitcher(fromActions).
InteractsWithTranslations
For less boilerplate, you can use the unified InteractsWithTranslations trait instead of page-specific traits:
use JeffersonGoncalves\FilamentTranslatable\Concerns\InteractsWithTranslations; class EditPost extends EditRecord { use InteractsWithTranslations; // Automatically detects the page type and provides // getTranslatableLocales() and locale management }
Configuration
// config/filament-translatable.php return [ /* |-------------------------------------------------------------------------- | Locale Flags |-------------------------------------------------------------------------- | | Map of locale codes to emoji flags. Used by the LocaleSwitcher and | TranslationStatusColumn to display visual locale indicators. | */ 'locale_flags' => [ 'en' => "\u{1F1FA}\u{1F1F8}", // US 'pt_BR' => "\u{1F1E7}\u{1F1F7}", // BR 'es' => "\u{1F1EA}\u{1F1F8}", // ES 'fr' => "\u{1F1EB}\u{1F1F7}", // FR 'de' => "\u{1F1E9}\u{1F1EA}", // DE // ... 25+ more built-in ], /* |-------------------------------------------------------------------------- | Flag Display Format |-------------------------------------------------------------------------- | | Controls how locale labels are displayed in the LocaleSwitcher. | Options: 'flag_and_label', 'flag_only', 'label_only' | */ 'flag_display' => 'flag_and_label', /* |-------------------------------------------------------------------------- | Translation Status Colors |-------------------------------------------------------------------------- | | Filament color names used by the TranslationStatusColumn badges. | */ 'status_colors' => [ 'complete' => 'success', 'partial' => 'warning', 'empty' => 'danger', ], ];
Migration from filament/spatie-laravel-translatable-plugin
This package is an enhanced fork of Filament's official translatable plugin. Migration is straightforward:
1. Replace the package:
composer remove filament/spatie-laravel-translatable-plugin
composer require jeffersongoncalves/filament-translatable:"^3.0"
2. Update PanelProvider imports:
// Before use Filament\SpatieLaravelTranslatablePlugin; // After use JeffersonGoncalves\FilamentTranslatable\FilamentTranslatablePlugin;
3. Update Resource and Page imports:
Replace Filament\Resources\ with JeffersonGoncalves\FilamentTranslatable\Resources\ in all translatable traits.
4. Update LocaleSwitcher imports:
// Before use Filament\Actions\LocaleSwitcher; // After (for pages) use JeffersonGoncalves\FilamentTranslatable\Actions\LocaleSwitcher; // After (for relation managers) use JeffersonGoncalves\FilamentTranslatable\Tables\Actions\LocaleSwitcher;
5. Enjoy the new features - Translation Status Column, locale flags, and status introspection are ready to use.
Testing
composer test
Changelog
Please see Releases for more information on what has changed recently.
License
The MIT License (MIT). Please see License File for more information.
