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

Locale Bundle Laravel Package

bastsys/locale-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the package via Composer:

    composer require bastsys/locale-bundle
    

    Register the bundle in config/bundles.php (Symfony) or config/app.php (Laravel via Symfony bridge):

    Bastsys\LocaleBundle\BastsysLocaleBundle::class => ['all' => true],
    
  2. Configuration Publish the default config:

    php artisan vendor:publish --provider="Bastsys\LocaleBundle\BastsysLocaleBundle" --tag="config"
    

    Update config/locale.php (or equivalent) to define supported locales and default locale:

    return [
        'locales' => ['en', 'cs', 'de'],
        'default_locale' => 'en',
    ];
    
  3. First Use Case: Localized Entity Labels Annotate a Doctrine entity (or Eloquent model via bridge) with Locale trait:

    use Bastsys\LocaleBundle\Model\LocaleTrait;
    
    class Product
    {
        use LocaleTrait;
    
        // Fields...
    }
    

    Add a name field with locale prefix (e.g., name_en, name_cs). Access translations dynamically:

    $product->getName('cs'); // Returns Czech translation
    

Implementation Patterns

1. Entity Localization Workflow

  • Field Naming Convention Use field_locale (e.g., title_en, description_cs) for multi-lingual fields. Avoid manual locale handling; leverage the LocaleTrait setter/getter methods:

    $product->setName('Smartphone', 'en');
    $product->getName('cs'); // Auto-fetches Czech translation
    
  • Default Locale Fallback Configure fallback locales in config/locale.php:

    'fallback_locales' => ['en' => ['cs', 'de']],
    

    Example: If name_cs is missing, it falls back to name_en.

  • Dynamic Locale Switching Use middleware (Symfony) or Laravel’s AppServiceProvider to set the locale:

    // Laravel (Symfony bridge)
    public function boot()
    {
        $locale = request()->header('Accept-Language') ?? config('locale.default_locale');
        app()->setLocale($locale);
    }
    

2. Integration with Forms

  • Symfony Forms Use LocaleType for locale-aware fields:
    $builder->add('name', LocaleType::class, [
        'locales' => ['en', 'cs'],
        'default_locale' => 'en',
    ]);
    
  • Laravel Collective Extend FormBuilder to support locale fields:
    Form::localeText('name', 'Product Name', ['locales' => ['en', 'cs']]);
    

3. API Responses

  • Localized JSON Responses Serialize entities with locale-aware fields:
    $product->toArray(['locale' => 'cs']); // Returns ['name' => 'Chytrý telefon']
    
    Use a custom JSON encoder or Laravel’s App\Transformers\ProductTransformer:
    public function transform(Product $product)
    {
        return [
            'name' => $product->getName(app()->getLocale()),
            // ...
        ];
    }
    

4. Database Migrations

  • Schema Design Add locale column to translation tables or use a single table with field_locale suffixes. Example migration:
    Schema::create('products', function (Blueprint $table) {
        $table->id();
        $table->string('name_en')->nullable();
        $table->string('name_cs')->nullable();
        // ...
    });
    

Gotchas and Tips

Pitfalls

  1. Locale Key Conflicts Avoid naming conflicts with existing fields (e.g., created_at_en). Use a consistent prefix like locale_ or _<locale>. Fix: Rename fields to locale_name_en or use a dedicated table for translations.

  2. Missing Fallback Logic If fallback_locales isn’t configured, missing translations return null. Fix: Set a default fallback in config/locale.php:

    'fallback_locales' => ['*' => ['en']], // Fallback to English for all locales
    
  3. Performance with Many Locales Querying all locale fields (e.g., SELECT * FROM products) bloats results. Fix: Use a query scope or select specific fields:

    $product = Product::where('id', $id)
        ->withLocale('en', 'cs') // Load only needed locales
        ->first();
    
  4. Doctrine vs. Eloquent The bundle is Doctrine-first. For Laravel/Eloquent:

    • Use a bridge like laravel-doctrine or rewrite accessors.
    • Example Eloquent accessor:
      public function getNameAttribute($value)
      {
          return $this->getName(app()->getLocale());
      }
      

Debugging Tips

  • Check Loaded Locales Log the current locale chain:
    \Log::debug('Active locales:', [
        'current' => app()->getLocale(),
        'fallbacks' => config('locale.fallback_locales'),
    ]);
    
  • Validate Field Names Ensure field names match the field_locale pattern. Use:
    $this->assertTrue($product->hasName('en')); // Checks if field exists
    

Extension Points

  1. Custom Locale Providers Override locale resolution by implementing LocaleProviderInterface:

    class SessionLocaleProvider implements LocaleProviderInterface
    {
        public function getLocale(): string
        {
            return session('locale', config('locale.default_locale'));
        }
    }
    

    Register in config/locale.php:

    'locale_provider' => Bastsys\LocaleBundle\Provider\SessionLocaleProvider::class,
    
  2. Dynamic Locale Fields Extend LocaleTrait to support runtime locale additions:

    // In a service or trait extension
    public function addLocaleField(string $field, string $locale): void
    {
        $this->{$field . '_' . $locale} = $this->{$field} ?? null;
    }
    
  3. Event Listeners Listen for locale.before_set and locale.after_get events to log or validate translations:

    // config/services.php
    'locale.listeners' => [
        App\Listeners\LocaleLogger::class,
    ];
    

Configuration Quirks

  • Caching The bundle doesn’t cache locale lookups by default. For high-traffic apps, cache the LocaleProvider:
    $locale = Cache::remember('active_locale', 3600, fn() => app()->getLocale());
    
  • Symfony vs. Laravel
    • Symfony: Uses RequestStack for locale detection.
    • Laravel: Override LocaleProvider to use Laravel’s Request or Session.
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.
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
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium