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

Laravel Translatable Laravel Package

latevaweb/laravel-translatable

Add translatable Eloquent attributes backed by a Translations database table. Use a Translatable trait to set/get per-locale values, auto-resolve attributes by current app locale, and store translations via polymorphic relations.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Install the Package Run composer require latevaweb/laravel-translatable to add the package to your project.

  2. Publish Config and Migrations Execute these commands to set up the required database tables and configurations:

    php artisan vendor:publish --provider="LaTevaWeb\Translatable\TranslatableServiceProvider" --tag=config --force
    php artisan vendor:publish --provider="LaTevaWeb\Translatable\TranslatableServiceProvider" --tag=migrations --force
    

    Run the migrations:

    php artisan migrate
    
  3. First Use Case: Basic Translation Add the Translatable trait and define translatable attributes in your model:

    use LaTevaWeb\Translatable\Traits\Translatable;
    
    class Product extends Model
    {
        use Translatable;
    
        public static $translatable = ['name', 'description'];
    }
    

    Set translations for a model instance:

    $product = new Product();
    $product->setTranslation('name', 'en', 'Laptop');
    $product->setTranslation('name', 'es', 'Portátil');
    $product->save();
    

    Retrieve translations dynamically:

    $product->name; // Returns 'Laptop' if app locale is 'en'
    $product->getTranslation('name', 'es'); // Returns 'Portátil'
    

Implementation Patterns

Usage Patterns

  1. Dynamic Locale Handling Leverage the package’s integration with Laravel’s locale system:

    app()->setLocale('es');
    $product->name; // Automatically returns 'Portátil'
    
  2. Mass Assignment with Translations Use fill() or create() with translations:

    $product = Product::create([
        'name_en' => 'Smartphone',
        'name_es' => 'Teléfono Inteligente',
        'description_en' => 'Latest model',
        'description_es' => 'Último modelo',
    ]);
    
  3. Querying Translated Attributes Filter models by translated attributes:

    $products = Product::whereTranslation('name', 'en', 'Laptop')->get();
    
  4. Fallback Locales Define a fallback locale in the config (e.g., config/translatable.php):

    'fallback_locale' => 'en',
    

    Then retrieve translations with a fallback:

    $product->getTranslation('name', 'fr'); // Returns 'Laptop' (fallback to 'en')
    

Workflows

  1. Multi-Language Admin Panel Use the package to store and retrieve translations for admin interfaces:

    // Admin sets translations
    $page->setTranslation('title', 'en', 'Home');
    $page->setTranslation('title', 'de', 'Startseite');
    $page->save();
    
    // Frontend displays based on user locale
    echo $page->title; // Automatically picks 'Home' or 'Startseite'
    
  2. Localization in API Responses Serialize translated attributes in API responses:

    return ProductResource::collection(
        Product::withTranslations(['name', 'description'])->get()
    );
    
  3. Seeding Translated Data Seed databases with translations:

    $product = Product::create(['slug' => 'prod-123']);
    $product->setTranslation('name', 'en', 'Headphones');
    $product->setTranslation('name', 'ja', 'ヘッドホン');
    $product->save();
    

Integration Tips

  1. Customize Table Names Override default table names in the config:

    'tables' => [
        'translations' => 'custom_translations',
        'models' => 'custom_models',
    ],
    
  2. Extend the Trait Add custom logic to the trait by overriding methods:

    use LaTevaWeb\Translatable\Traits\Translatable;
    
    class Product extends Model
    {
        use Translatable;
    
        public function setTranslation($attribute, $locale, $value)
        {
            // Custom logic before saving
            $value = strtoupper($value);
            parent::setTranslation($attribute, $locale, $value);
        }
    }
    
  3. Use with Eloquent Relationships Combine with polymorphic relationships:

    class Translation extends Model
    {
        public function translatable()
        {
            return $this->morphTo();
        }
    }
    
  4. Cache Translations Cache frequently accessed translations to reduce database load:

    $translation = Cache::remember("product_{$product->id}_name_{$locale}", now()->addHours(1), function () use ($product, $locale) {
        return $product->getTranslation('name', $locale);
    });
    

Gotchas and Tips

Pitfalls

  1. Locale Dependency

    • Issue: Translations rely on the current app locale. If the locale isn’t set, the package may return null or fall back to a default.
    • Fix: Always set a default locale in AppServiceProvider:
      public function boot()
      {
          app()->setLocale(config('app.fallback_locale'));
      }
      
  2. Missing Migrations

    • Issue: Forgetting to run migrations after publishing will cause TranslationNotFoundException.
    • Fix: Always run php artisan migrate after publishing migrations.
  3. Attribute Not Defined in $translatable

    • Issue: Attempting to translate an attribute not listed in public static $translatable will silently fail or throw an error.
    • Fix: Ensure all translatable attributes are listed:
      public static $translatable = ['name', 'description', 'meta_title'];
      
  4. Polymorphic Conflicts

    • Issue: If your model already uses a translatable_id or translatable_type column, the package’s migrations may conflict.
    • Fix: Customize the migration or rename conflicting columns.
  5. Performance with Large Datasets

    • Issue: Querying translations for many records can be slow if not optimized.
    • Fix: Use eager loading:
      $products = Product::withTranslations(['name'])->get();
      
  6. Laravel Version Mismatch

    • Issue: The package is primarily tested for Laravel 8. Using it in Laravel 9/10 may cause unexpected behavior.
    • Fix: Test thoroughly or fork the package for newer Laravel versions.

Debugging

  1. Check Database Records Verify translations are stored correctly:

    php artisan tinker
    >>> \DB::table('translations')->where('translatable_id', $product->id)->get();
    
  2. Enable Query Logging Debug SQL queries in AppServiceProvider:

    public function boot()
    {
        \DB::enableQueryLog();
    }
    

    Then inspect logs:

    >>> \DB::getQueryLog();
    
  3. Validate Config Ensure the config file is published and correctly set:

    php artisan config:clear
    
  4. Check for Caching Issues Clear caches if translations aren’t updating:

    php artisan config:clear
    php artisan cache:clear
    php artisan view:clear
    

Tips

  1. Use Accessors for Dynamic Logic Override accessors to add logic when fetching translations:

    public function getNameAttribute($value)
    {
        $locale = app()->getLocale();
        return $this->getTranslation('name', $locale) ?: $value;
    }
    
  2. Leverage Scopes Create custom scopes for querying translated content:

    public function scopeInLanguage($query, $locale)
    {
        return $query->whereHas('translations', function ($q) use ($locale) {
            $q->where('locale', $locale);
        });
    }
    
  3. Batch Translation Updates Use chunking for bulk updates:

    Product::chunk(200, function ($products) {
        foreach ($products as $product) {
            $product->setTranslation('description', 'en', 'Updated description');
            $product->save();
        }
    });
    
  4. Localization in Blade Views Use the package in Blade templates:

    <h1>{{ $product->getTranslation('name', session('locale')) }}</h1>
    
  5. Testing Translations Write tests to verify translations:

    public function test_translations()
    {
        $product = Product::factory()->create();
        $product->setTranslation('name', 'en', 'Test Product');
        $this->assertEquals('Test Product', $product->name);
    }
    
  6. Extend the Translation Model Add custom

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.
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
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