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

Translation Bundle Laravel Package

c4/translation-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require c4/translation-bundle
    

    Add to config/app.php under providers:

    C4\TranslationBundle\TranslationBundle::class,
    
  2. Configuration Publish the default config:

    php artisan vendor:publish --provider="C4\TranslationBundle\TranslationBundle" --tag="config"
    

    Key settings to review:

    • default_locale (e.g., en)
    • supported_locales (e.g., ['en', 'fr', 'de'])
    • fallback_locale (e.g., en)
  3. First Use Case: Basic Translation Define translations in resources/lang/{locale}/messages.php:

    return [
        'welcome' => 'Welcome, :name!',
    ];
    

    Use in Blade:

    {{ trans('messages.welcome', ['name' => 'John']) }}
    

    Or in PHP:

    __('messages.welcome', ['name' => 'John']);
    

Implementation Patterns

1. Locale Management

  • Dynamic Locale Switching Use middleware to set locale from URL or session:

    // app/Http/Middleware/SetLocale.php
    public function handle($request, Closure $next) {
        $locale = $request->segment(1) ?? config('app.locale');
        app()->setLocale($locale);
        return $next($request);
    }
    

    Register in app/Http/Kernel.php:

    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\SetLocale::class,
            // ...
        ],
    ];
    
  • Locale Prefix in Routes Configure routes to handle /{locale}/...:

    Route::prefix('{locale}')->where('locale', implode('|', config('translation.supported_locales')))->group(function () {
        Route::get('/', 'HomeController@index');
    });
    

2. JSON Translation Files

  • Store translations in resources/lang/{locale}/{namespace}.json:
    // resources/lang/fr/messages.json
    {
        "welcome": "Bienvenue, :name !"
    }
    
  • Load via:
    __('messages.welcome', ['name' => 'Marie']);
    

3. Validation Messages

  • Override default validation messages per locale:
    // config/translation.php
    'validation' => [
        'custom' => [
            'required' => [
                'fr' => 'Le champ :attribute est requis.',
                'de' => 'Das Feld :attribute ist erforderlich.',
            ],
        ],
    ];
    

4. Fallback Logic

  • Configure fallback chain in config/translation.php:
    'fallbacks' => [
        'fr' => ['en'],
        'de' => ['en'],
    ],
    
  • Ensures translations fall back to en if fr or de are missing.

5. Translation Loading Order

  • The bundle loads translations in this order:
    1. JSON files (if namespace matches).
    2. PHP files (messages.php).
    3. Fallback locales.

6. Custom Namespaces

  • Define custom namespaces in config/translation.php:
    'namespaces' => [
        'validation' => 'validation',
        'auth' => 'auth',
    ],
    
  • Use in Blade:
    {{ trans('validation.required', ['attribute' => 'email']) }}
    

7. Translation Dump

  • Generate a translation dump for all locales:
    php artisan translation:dump
    
  • Useful for initializing new locales or checking coverage.

Gotchas and Tips

Pitfalls

  1. Locale Not Set

    • If app()->getLocale() returns null, translations will fail silently.
    • Fix: Ensure config('app.locale') is set and middleware is applied.
  2. Missing Fallback Config

    • If fallback_locale is not set, missing translations will return the key instead of the key itself.
    • Fix: Always define fallback_locale in config/translation.php.
  3. JSON Syntax Errors

    • JSON files must be valid; syntax errors will cause silent failures.
    • Fix: Validate JSON files manually or use a linter.
  4. Caching Issues

    • After adding new locales or translations, clear the view cache:
      php artisan view:clear
      php artisan cache:clear
      
  5. Namespace Conflicts

    • If two files define the same key (e.g., messages.php and messages.json), the last loaded file wins.
    • Fix: Use distinct namespaces or merge files.
  6. Route Locale Conflicts

    • If using {locale} in routes, ensure it doesn’t conflict with other route parameters.
    • Fix: Use where() constraints:
      Route::get('/{locale}/user/{id}', function ($locale, $id) { ... })
          ->where('locale', implode('|', config('translation.supported_locales')));
      

Debugging Tips

  1. Check Loaded Translations Dump all loaded translations for debugging:

    dd(app('translator')->getLoader()->getNamespaces());
    
  2. Verify Locale Log the current locale to ensure it’s set correctly:

    \Log::debug('Current locale:', ['locale' => app()->getLocale()]);
    
  3. Test Fallback Logic Temporarily remove a translation file to test fallback:

    mv resources/lang/fr/messages.php resources/lang/fr/messages.php.bak
    

Extension Points

  1. Custom Loaders Extend the loader to support additional file formats (e.g., YAML):

    // app/Providers/TranslationServiceProvider.php
    public function boot() {
        $loader = $this->app['translator']->getLoader();
        $loader->addLoader('yaml', function () {
            return new YamlLoader();
        });
    }
    
  2. Dynamic Translation Sources Fetch translations from an API or database:

    $loader = $this->app['translator']->getLoader();
    $loader->addLoader('api', function () {
        return new ApiTranslationLoader();
    });
    
  3. Middleware for Locale Persistence Store locale in session or cookies for better UX:

    // app/Http/Middleware/PersistLocale.php
    public function handle($request, Closure $next) {
        if ($request->hasCookie('locale')) {
            app()->setLocale($request->cookie('locale'));
        }
        return $next($request);
    }
    
  4. Translation Editor Build a simple admin interface to edit translations via a form:

    // routes/web.php
    Route::get('/admin/translations', 'TranslationController@edit');
    Route::post('/admin/translations', 'TranslationController@update');
    

Performance Tips

  1. Cache Translations Enable translation caching for production:

    // config/translation.php
    'cache' => env('APP_ENV') === 'production',
    
  2. Preload Translations Preload translations for critical locales during boot:

    // app/Providers/AppServiceProvider.php
    public function boot() {
        app('translator')->load('messages', 'en');
        app('translator')->load('messages', 'fr');
    }
    
  3. Avoid Over-Translating Only translate strings that appear in the UI. Avoid translating:

    • Internal logic strings (e.g., if ($user->is_active)).
    • Database column names or API responses.
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.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui