qsque/filament-translation-helper

A Filament plugin that provides automatic translations with fallback support for resources, forms and tables

Installs: 35

Dependents: 0

Suggesters: 0

Security: 0

Stars: 2

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/qsque/filament-translation-helper

1.0.6 2025-10-26 11:09 UTC

This package is not auto-updated.

Last update: 2026-01-04 12:08:23 UTC


README

Latest Version on Packagist Total Downloads License

A powerful Filament plugin that provides automatic translations with intelligent fallback support for forms, tables, and resources.

Installation β€’ Quick Start β€’ Features

✨ Features

  • πŸ”„ Automatic Translation Discovery: Fields, columns, and sections are automatically translated
  • 🎯 Smart Fallback System: Local translations β†’ Package translations β†’ Auto-generated labels
  • 🌐 Multi-language Support: Built-in language switching with session persistence
  • πŸ“ Zero Configuration: Works out of the box without any setup
  • 🎨 Language Switcher: Ready-to-use user menu item for your admin panel
  • ⚑ Laravel 11 & 12 Support: Compatible with the latest Laravel versions
  • 🎯 Filament 4 Ready: Built for the latest Filament architecture
  • πŸ”§ Highly Configurable: Customize locales, fallbacks, and translation paths

πŸš€ Installation

Install the package via Composer:

composer require qsque/filament-translation-helper

That's it! The package works out of the box with zero configuration. πŸŽ‰

⚑ Quick Start

1. Basic Usage (Zero Config)

Just use your forms and tables as usual - translations happen automatically:

Resource:

use Qsque\FilamentTranslationHelper\Resources\BaseResource;

class UserResource extends BaseResource
{
    protected static ?string $model = User::class;
    
    // Resource labels are automatically translated from:
    // resources.user.label and resources.user.plural_label
}

Form:

use Filament\Forms\Form;
use Filament\Forms\Components\TextInput;

public function form(Form $form): Form
{
    return $form->schema([
        TextInput::make('name'),        // β†’ "Name" or translated
        TextInput::make('email'),       // β†’ "Email" or translated
        TextInput::make('first_name'),  // β†’ "First Name" or translated
    ]);
}

Table:

use Filament\Tables\Table;
use Filament\Tables\Columns\TextColumn;

public function table(Table $table): Table
{
    return $table->columns([
        TextColumn::make('name'),       // β†’ "Name" or translated
        TextColumn::make('created_at'), // β†’ "Created At" or translated
    ]);
}

2. Add Translation Files (Optional)

Create translation files for custom labels:

// lang/en/common.php
return [
    'fields' => [
        'name' => 'Full Name',
        'email' => 'Email Address',
        'created_at' => 'Registration Date',
    ],
];

// lang/ru/common.php  
return [
    'fields' => [
        'name' => 'ПолноС имя',
        'email' => 'Email адрСс',
        'created_at' => 'Π”Π°Ρ‚Π° рСгистрации',
    ],
];

3. Add Language Switcher (Optional)

use Qsque\FilamentTranslationHelper\Components\LanguageSwitcher;

public function panel(Panel $panel): Panel
{
    return $panel
        ->userMenuItems([
            LanguageSwitcher::getUserMenuItem(),
        ]);
}

🎯 How It Works

Translation Lookup Strategy

The plugin automatically translates fields using this intelligent fallback system:

graph TD
    A[Field: 'first_name'] --> B{Resource-specific translation?}
    B -->|Yes| C[resources.user.fields.first_name]
    B -->|No| D{Common field translation?}
    D -->|Yes| E[common.fields.first_name]
    D -->|No| F{Package translation?}
    F -->|Yes| G[filament-translation-helper::common.fields.first_name]
    F -->|No| H{Base name translation?}
    H -->|Yes| I[common.fields.first (for 'first_name')]
    H -->|No| J[Auto-generate: 'First Name']
Loading

Translation Hierarchy Examples

Field Name Translation Lookup Order
name resources.user.fields.name β†’ common.fields.name β†’ "Name"
email resources.user.fields.email β†’ common.fields.email β†’ "Email"
config.api_key resources.user.fields.config.api_key β†’ common.fields.config β†’ "Config"

πŸ“ Translation File Structure

Resource-Specific Translations

// lang/en/resources.php
return [
    'user' => [
        'label' => 'User',
        'plural_label' => 'Users',
        'fields' => [
            'name' => 'User Name',
            'email' => 'Email Address',
        ],
        'sections' => [
            'general' => 'General Information',
            'security' => 'Security Settings',
        ],
        'columns' => [
            'created_at' => 'Registration Date',
        ],
    ],
];

Common Field Translations

// lang/en/common.php
return [
    'fields' => [
        'name' => 'Name',
        'email' => 'Email',
        'password' => 'Password',
        'created_at' => 'Created At',
        'updated_at' => 'Updated At',
        // ... hundreds of pre-built translations
    ],
];

πŸ”§ Advanced Configuration

Custom Configuration

Publish the config file to customize behavior:

php artisan vendor:publish --tag="filament-translation-helper-config"
// config/filament-translation-helper.php
return [
    'available_locales' => [
        'en' => 'English',
        'ru' => 'Русский',
        'es' => 'EspaΓ±ol',
        'fr' => 'FranΓ§ais',
        'de' => 'Deutsch',
    ],
    
    'default_locale' => env('APP_LOCALE', 'en'),
    
    'fallback_locale' => 'en',
    
    'session_key' => 'filament_locale',
];

Custom Resource Keys

Override the resource translation key:

class UserProfileResource extends Resource
{
    protected static function getResourceKey(): string
    {
        return 'user-profile'; // Uses resources.user-profile.*
    }
}

Middleware Setup (Optional)

Add locale persistence across requests:

use Qsque\FilamentTranslationHelper\Http\Middleware\SetLocale;

public function panel(Panel $panel): Panel
{
    return $panel
        ->middleware([
            SetLocale::class,
        ]);
}

πŸ› οΈ Advanced Usage

Manual Translation Helper

use Qsque\FilamentTranslationHelper\Support\TranslationHelper;

// Get translation with automatic fallback
$label = TranslationHelper::getWithFallback('sections.user_details');
// Returns: "User Details" (auto-generated) or actual translation

// Check if translation exists
if (TranslationHelper::hasTranslation('common.fields.custom_field')) {
    // Use translation
}

BaseResource Class

Extend BaseResource for automatic resource label translation:

use Qsque\FilamentTranslationHelper\Resources\BaseResource;

class UserResource extends BaseResource
{
    protected static ?string $model = User::class;
    
    // Automatically translates:
    // - getLabel() from resources.user.label
    // - getPluralLabel() from resources.user.plural_label
}

Custom Translation Logic

use Qsque\FilamentTranslationHelper\Contracts\TranslationStrategy;

class CustomTranslationStrategy implements TranslationStrategy
{
    public function getTranslation(string $key, string $fallback = null): string
    {
        // Your custom translation logic
    }
}

πŸ“¦ Package Translations

The package includes pre-built translations for common fields in multiple languages:

  • English (en)
  • Russian (ru)

Publishing Package Translations

# Publish to customize package translations
php artisan vendor:publish --tag="filament-translation-helper-lang"

🎨 Language Switcher Customization

Basic Usage

// In your PanelProvider
public function panel(Panel $panel): Panel
{
    return $panel
        ->userMenuItems([
            LanguageSwitcher::getUserMenuItem(),
        ]);
}

Custom Implementation

// You can also implement your own user menu item
use Filament\Support\Facades\FilamentView;
use Filament\Navigation\MenuItem;
use Filament\Forms\Components\Radio;

MenuItem::make()
    ->label(config('filament-translation-helper.available_locales')[app()->getLocale()])
    ->icon('heroicon-o-language')
    ->form([
        Radio::make('locale')
            ->options(config('filament-translation-helper.available_locales'))
            ->default(app()->getLocale())
            ->inline(false)
            ->hiddenLabel(),
    ])
    ->action(function (array $data) {
        return redirect()->to(route('locale.switch', $data['locale']));
    })

πŸ” Examples in Action

Form Example

use Filament\Forms\Form;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Forms\Components\Section;

public function form(Form $form): Form
{
    return $form->schema([
        Section::make('general') // β†’ "General" or translated
            ->schema([
                TextInput::make('name')      // β†’ "Name" or translated
                    ->required(),
                TextInput::make('email')     // β†’ "Email" or translated
                    ->email(),
            ]),
            
        Section::make('settings')    // β†’ "Settings" or translated
            ->schema([
                Toggle::make('is_active') // β†’ "Is Active" or translated
                    ->default(true),
            ]),
    ]);
}

Table Example

use Filament\Tables\Table;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Columns\BooleanColumn;

public function table(Table $table): Table
{
    return $table
        ->columns([
            TextColumn::make('id')         // β†’ "ID"
                ->sortable(),
            TextColumn::make('name')       // β†’ "Name" or translated
                ->searchable(),
            TextColumn::make('email')      // β†’ "Email" or translated
                ->searchable(),
            BooleanColumn::make('is_active') // β†’ "Is Active" or translated,
            TextColumn::make('created_at') // β†’ "Created At" or translated
                ->dateTime(),
        ]);
}

πŸ“„ License

The MIT License (MIT). Please see License File for more information.

πŸ’ Credits

Made with ❀️ for the Filament community

⭐ Star on GitHub β€’ πŸ› Report Issues β€’ πŸ’¬ Discussions