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

Common I18N Laravel Package

binsoul/common-i18n

Common i18n utilities for PHP applications. Provides lightweight helpers for working with translations and locales, aiming to reduce boilerplate around internationalization in shared code across projects.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require binsoul/common-i18n
    

    Publish the config file (if available):

    php artisan vendor:publish --provider="Binsoul\CommonI18n\CommonI18nServiceProvider"
    
  2. Basic Configuration Edit config/common-i18n.php to define:

    • Default locale (default_locale)
    • Supported locales (locales)
    • Fallback locale (fallback_locale)
    • Translation paths (e.g., paths for JSON/CSV files)
  3. First Use Case: Localizing Strings Load translations in a controller or service:

    use Binsoul\CommonI18n\Facades\I18n;
    
    $greeting = I18n::trans('greetings.hello'); // Assumes 'en' locale
    
  4. Locale Switching Dynamically switch locales in middleware or routes:

    I18n::setLocale('fr'); // Force French locale
    

Implementation Patterns

1. Translation Management

  • JSON/CSV Files: Store translations in resources/lang/{locale}/messages.json or .csv. Example (en/messages.json):
    {
      "greetings": {
        "hello": "Hello, {{ name }}!"
      }
    }
    
  • Dynamic Keys: Use placeholders (e.g., {{ name }}) for runtime values:
    I18n::trans('greetings.hello', ['name' => 'John']);
    

2. Middleware for Locale Routing

Bind locales to routes (e.g., /fr/dashboard):

Route::prefix('{locale}')->middleware('locale')->group(function () {
    // Routes here
});

Middleware (app/Http/Middleware/LocaleMiddleware.php):

public function handle($request, Closure $next) {
    I18n::setLocale($request->locale);
    return $next($request);
}

3. Fallback Logic

Configure fallback locales in config/common-i18n.php:

'fallback_locale' => 'en',
'fallback_chain'  => ['en', 'fr'],

The package will automatically fall back if a translation is missing.

4. Integration with Blade

Extend Blade directives for inline translations:

// Add to AppServiceProvider::boot()
Blade::directive('trans', function ($expression) {
    return "<?php echo \Binsoul\CommonI18n\Facades\I18n::trans($expression); ?>";
});

Usage in Blade:

<h1>@trans('greetings.hello', ['name' => 'Alice'])</h1>

5. Validation Messages

Override Laravel’s validation messages:

$validator = Validator::make($data, $rules);
$validator->setMessages(I18n::getValidatorMessages());

6. Testing

Mock translations in tests:

I18n::setLocale('test');
I18n::translator()->set('test.key', 'Mocked value');
$this->assertEquals('Mocked value', I18n::trans('test.key'));

Gotchas and Tips

Pitfalls

  1. Missing Config Keys Ensure config/common-i18n.php exists and is properly configured. The package may silently fail if paths or locales are misconfigured.

    • Fix: Run php artisan vendor:publish and verify the config.
  2. Locale Not Set If I18n::getLocale() returns null, translations will fail. Always set a default locale in the config or middleware.

    • Fix:
      I18n::setLocale(config('app.locale', 'en'));
      
  3. Caching Issues Translations may not update if the cache is enabled. Clear the cache after adding new translations:

    php artisan cache:clear
    php artisan view:clear
    
  4. CSV Parsing Quirks The package may not handle malformed CSV files gracefully. Validate your CSV structure (e.g., UTF-8 encoding, no extra commas).

    • Tip: Use a tool like CSVLint to validate files before importing.
  5. Namespace Conflicts If you have a class or trait named I18n, the facade may conflict. Rename or alias the facade:

    use Binsoul\CommonI18n\Facades\I18n as I18nTranslator;
    

Debugging Tips

  • Check Loaded Translations:
    dd(I18n::translator()->get('*')); // Dump all loaded translations
    
  • Enable Debug Mode:
    I18n::translator()->setDebug(true); // Logs missing translations
    
  • Log Missing Keys: Add this to AppServiceProvider::boot():
    I18n::translator()->setMissingCallback(function ($key) {
        Log::warning("Missing translation key: {$key}");
    });
    

Extension Points

  1. Custom Translator Extend the translator for database-backed translations:

    I18n::translator()->extend('db', function ($locale) {
        return new DatabaseTranslator($locale);
    });
    I18n::translator()->setTranslator('db');
    
  2. Pluralization Rules Override pluralization logic for languages like Arabic or Russian:

    I18n::translator()->setPluralizer('ar', function ($count) {
        return $count == 1 ? 'singular' : 'plural';
    });
    
  3. Add New File Formats Implement a custom loader for YAML or XML:

    I18n::translator()->addLoader('yaml', function ($locale, $loader) {
        return new YamlLoader($locale, $loader);
    });
    
  4. Locale Detection Integrate with user agents or cookies for automatic locale detection:

    $locale = request()->cookie('locale') ?? request()->header('Accept-Language');
    I18n::setLocale($locale);
    

Performance Tips

  • Preload Translations: Load frequently used translations early (e.g., in a service provider):
    I18n::translator()->load('en', 'common', 'messages');
    
  • Disable Fallbacks in Production: Set 'fallback_locale' => null in production to fail fast on missing translations.
  • Use JSON for Large Files: JSON is faster to parse than CSV for large translation sets. Example:
    // resources/lang/en/messages.json
    {
      "validation": {
        "required": "The {{ field }} field is required."
      }
    }
    
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