Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Filament Plugin Translatable Inline Laravel Package

mvenghaus/filament-plugin-translatable-inline

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Package

    composer require mvenghaus/filament-plugin-translatable-inline:"^3.0"
    

    Ensure your project uses Filament v3 and has spatie/laravel-translatable as a dependency (handled automatically).

  2. Configure Spatie Translatable Plugin Follow the Filament Spatie Translatable Plugin docs to register the plugin in your AppServiceProvider or FilamentServiceProvider:

    Filament::registerPlugin(
        TranslatablePlugin::make()
            ->locales(['en', 'de', 'fr']) // Define your locales
    );
    
  3. Add Translatable Trait to Your Model Ensure your Eloquent model uses the Translatable trait:

    use Spatie\Translatable\HasTranslations;
    
    class Post extends Model
    {
        use HasTranslations;
    
        public $translatable = ['title', 'content']; // Fields to translate
    }
    
  4. Use the Plugin in a Resource Replace the default Translatable trait in your Form with the inline plugin’s trait:

    use Mvenghaus\FilamentPluginTranslatableInline\Forms\Components\Translatable;
    
    public static function form(Form $form): Form
    {
        return $form
            ->schema([
                Translatable::make('title') // Inline translation container
                    ->label('Title')
                    ->required(),
                // Other fields...
            ]);
    }
    
  5. First Use Case Edit a record in your Filament admin panel. Translations now appear inline below each field (e.g., title_en, title_de) instead of a dropdown locale switcher. Missing translations are visually highlighted.


Implementation Patterns

Workflow: Inline Translation Editing

  1. Field-Level Translations Wrap any translatable field in Translatable::make():

    Translatable::make('content')
        ->label('Content')
        ->columns(2) // Adjust layout (optional)
        ->extraAttributes(['class' => 'mt-4']),
    
    • Pro Tip: Use columns() to control how many translations appear side-by-side (e.g., columns(3) for 3 locales).
  2. Dynamic Locale Handling Leverage the plugin’s built-in locale detection:

    Translatable::make('description')
        ->locales(['en', 'es', 'pt']) // Override default locales
        ->defaultLocale('en'), // Set fallback
    
  3. Integration with Existing Forms

    • Replace only the Translatable header/action from the Spatie plugin with this inline component.
    • Keep other form logic (validation, relationships) unchanged.
  4. Partial Translations Use fillable or guarded in your model to control which fields support translations:

    protected $translatable = ['title', 'excerpt']; // Only these fields
    
  5. Conditional Translations Hide non-translatable fields or show placeholders:

    Translatable::make('slug')
        ->hidden(fn ($record) => !$record->isTranslatable()),
    

Advanced Patterns

  1. Custom Translation Labels Override the default locale labels (e.g., "English" → "EN"):

    Translatable::make('name')
        ->localeLabels(['en' => '🇬🇧', 'de' => '🇩🇪']),
    
  2. Nested Translations For nested resources, ensure the parent model’s translations are loaded:

    public static function form(Form $form): Form
    {
        return $form
            ->schema([
                Translatable::make('parent.title'), // Nested field
                // ...
            ]);
    }
    
  3. Bulk Translation Updates Use Filament’s bulk actions to update translations across records:

    public static function table(Table $table): Table
    {
        return $table
            ->actions([
                Tables\Actions\EditAction::make()->button(),
                TranslatableBulkAction::make(), // Hypothetical (extend if needed)
            ]);
    }
    
  4. Fallback Logic Combine with Spatie’s fallbackLocale in config/translatable.php:

    'fallback_locale' => 'en',
    

Gotchas and Tips

Pitfalls

  1. Double Registration

    • Error: Class 'Translatable' not found or duplicate locale headers.
    • Fix: Ensure only this plugin’s Translatable component is used in forms. Remove any TranslatableHeader or TranslatableAction from the Spatie plugin.
  2. Missing Translations

    • Issue: Inline fields appear empty for missing locales.
    • Debug: Check php artisan translate:fallback (Spatie command) or manually set defaults in the model:
      public function getTitleAttribute($value)
      {
          return $value ?? __('fallback.title');
      }
      
  3. Locale Mismatch

    • Error: Translations save to wrong locale (e.g., title_de saved as title_en).
    • Fix: Verify locales() in the plugin config match your model’s $translatable fields.
  4. Performance with Large Fields

    • Problem: Slow rendering for fields with long text (e.g., content).
    • Solution: Use columns(1) or lazy-load translations via JavaScript:
      Translatable::make('content')
          ->extraAttributes(['data-lazy' => 'true']),
      

Debugging Tips

  1. Check the Database Run php artisan tinker and inspect a record:

    $post = App\Models\Post::find(1);
    $post->getTranslations('title'); // Should return ['en' => '...', 'de' => '...']
    
  2. Log Locale Data Add a temporary dump in your AppServiceProvider:

    public function boot()
    {
        \Log::info('Translatable locales:', config('translatable.locales'));
    }
    
  3. Clear Cached Views If translations don’t appear:

    php artisan view:clear
    php artisan cache:clear
    

Extension Points

  1. Custom Styling Override the inline container’s Blade template in resources/views/vendor/filament-plugin-translatable-inline/translatable.blade.php:

    <div class="custom-translation-container">
        @foreach($locales as $locale)
            <div class="locale-field">
                {{ $field->getLabel($locale) }}
                {{ $field->getField($locale) }}
            </div>
        @endforeach
    </div>
    
  2. Add Validation Extend the component to validate translations per locale:

    Translatable::make('title')
        ->rules([
            'en' => 'required|min:3',
            'de' => 'nullable|max:50',
        ]),
    
  3. Localization of UI Text Publish and translate the plugin’s language lines:

    php artisan vendor:publish --tag=filament-plugin-translatable-inline-lang
    

    Then add translations to resources/lang/{locale}/filament-plugin-translatable-inline.php.

  4. Hook into Translation Events Listen for translatable.saving or translatable.saved events (Spatie’s events) to log or modify translations:

    use Spatie\Translatable\Events\TranslatableSaved;
    
    TranslatableSaved::listen(function ($model, $translations) {
        \Log::info("Translations saved for {$model->id}:", $translations);
    });
    
  5. Support for Filament Panels If using multiple panels, ensure the plugin is registered in each panel’s service provider:

    Filament::registerPlugin(
        TranslatablePlugin::make()->locales(['en', 'fr']),
        panel: 'admin' // Target specific panel
    );
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope