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

Php I18N L10N Laravel Package

wdes/php-i18n-l10n

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require wdes/php-i18n-l10n
    

    Ensure your composer.json meets the package’s requirements (PHP 8.1+, Twig 3.20+).

  2. Basic Setup:

    • For Twig templates, register the I18n extension in your TwigEnvironment:
      use Wdes\phpI18nL10n\Twig\Extension\I18n as ExtensionI18n;
      $twig->addExtension(new ExtensionI18n());
      
    • For direct PHP usage, initialize the MoReader plugin:
      use Wdes\phpI18nL10n\plugins\MoReader;
      use Wdes\phpI18nL10n\Launcher;
      
      $moReader = new MoReader();
      $moReader->setTranslations(['key' => 'translated value']);
      Launcher::setPlugin($moReader);
      
  3. First Use Case:

    • Twig: Use the {% trans %} tag in templates:
      {% trans %}Homepage{% endtrans %}
      
    • PHP: Translate strings dynamically:
      echo Launcher::getPlugin()->translate('key');
      
  4. Locale Configuration:

    • Set the default locale via Laravel’s AppServiceProvider:
      app()->setLocale('fr');
      
    • Override per-request in middleware:
      $request->setLocale('es');
      

Implementation Patterns

Core Workflows

1. Translation Management

  • Static Translations (e.g., admin panels):
    $moReader->setTranslations([
        'dashboard.title' => 'Tableau de bord',
        'dashboard.welcome' => 'Bienvenue, {{ name }}!'
    ]);
    
  • MO File Loading (e.g., for user-facing content):
    $moReader->readFile(base_path('lang/fr/translations.mo'));
    
  • Fallback Chains: Configure fallback locales in config/i18n.php:
    'fallbacks' => [
        'fr' => ['en'],
        'es' => ['en'],
    ],
    

2. Dynamic Locale Handling

  • Middleware for Locale Detection:
    public function handle($request, Closure $next) {
        $locale = app(\Wdes\phpI18nL10n\LocaleDetector::class)
            ->detect($request->header('Accept-Language'));
        app()->setLocale($locale);
        return $next($request);
    }
    
  • Route-Based Locales:
    Route::prefix('{locale}')->middleware('set.locale')->group(function () {
        // ...
    });
    

3. Twig Integration

  • Custom Filters/Functions:
    $twig->addFunction(new \Twig\TwigFunction(
        'pluralize',
        [Launcher::getPlugin(), 'pluralize']
    ));
    
    Usage in Twig:
    {{ pluralize('item', count) }}
    
  • Translation Context:
    {% trans %}messages.new{% endtrans %}  {# Outputs "Nouveau message" in French #}
    

4. Locale-Aware Formatting

  • Dates/Numbers/Currencies:
    $formatter = new \Wdes\phpI18nL10n\Formatter('fr');
    echo $formatter->formatDate(new \DateTime(), 'full');
    echo $formatter->formatNumber(1000.5, 'currency');
    

Laravel-Specific Patterns

Service Provider Integration

public function register() {
    $this->app->singleton(\Wdes\phpI18nL10n\I18n::class, function ($app) {
        $moReader = new \Wdes\phpI18nL10n\plugins\MoReader();
        $moReader->readFile(base_path('lang/'.app()->getLocale().'.mo'));
        return new \Wdes\phpI18nL10n\I18n($moReader);
    });
}

Facade Wrapper

// app/Facades/I18nFacade.php
namespace App\Facades;

use Illuminate\Support\Facades\Facade;

class I18nFacade extends Facade {
    protected static function getFacadeAccessor() {
        return \Wdes\phpI18nL10n\I18n::class;
    }
}

Usage:

use App\Facades\I18nFacade;

echo I18nFacade::translate('key');

Validation Rules

use Wdes\phpI18nL10n\Validator;

$validator = new Validator();
$validator->validate('email', $request->input('email'), 'required|email', [
    'email.required' => 'Le champ email est obligatoire.',
]);

Gotchas and Tips

Pitfalls

  1. Locale Mismatch:

    • Issue: Forgetting to set the locale before translation calls.
    • Fix: Use middleware or service provider to auto-set the locale:
      app()->setLocale($request->getPreferredLanguage());
      
  2. MO File Parsing Errors:

    • Issue: Corrupted .mo files may crash the MoReader.
    • Fix: Validate files with the package’s validateMoFile() method or use the scripts/tools/validate-mo.sh tool.
  3. Twig Extension Conflicts:

    • Issue: Conflicts with Laravel’s built-in trans filter if both are registered.
    • Fix: Unregister Laravel’s Twig extensions or namespace the custom extension:
      $twig->addExtension(new ExtensionI18n('custom_'));
      
      Usage in Twig:
      {{ custom_trans('key') }}
      
  4. Pluralization Edge Cases:

    • Issue: Incorrect plural forms for unsupported languages.
    • Fix: Extend the Pluralizer class or use the package’s addPluralRule() method:
      Launcher::getPlugin()->addPluralRule('ar', [
          '=0' => '{{count}} Item',
          '=1' => '{{count}} Item',
          '=2' => '{{count}} Items',
          'many' => '{{count}} Items',
      ]);
      
  5. Performance with Large MO Files:

    • Issue: Slow loading of giant translation files.
    • Fix: Cache the MoReader instance:
      $this->app->singleton(MoReader::class, function () {
          $reader = new MoReader();
          $reader->readFile($moFilePath);
          return $reader;
      });
      

Debugging Tips

  1. Translation Dumps:
    dd(Launcher::getPlugin()->getTranslations());
    
  2. Locale Logging: Add middleware to log detected locales:
    public function handle($request, Closure $next) {
        logger()->debug("Detected locale: {$request->getLocale()}");
        return $next($request);
    }
    
  3. Twig Debugging: Enable Twig’s debug mode:
    $twig = new \Twig\Environment($loader, [
        'debug' => config('app.debug'),
    ]);
    

Extension Points

  1. Custom Plugins: Extend BasePlugin to support new translation sources (e.g., database):

    class DbReader extends BasePlugin {
        public function getTranslations() {
            return DB::table('translations')->pluck('value', 'key')->toArray();
        }
    }
    
  2. Formatter Extensions: Add custom formatters for niche locales:

    $formatter = new \Wdes\phpI18nL10n\Formatter('ja');
    $formatter->addRule('date.short', 'Y/m/d');
    
  3. Locale-Specific Logic: Override default behavior per locale:

    Launcher::getPlugin()->on('fr', function ($translator) {
        $translator->setFallback('en');
    });
    

Configuration Quirks

  1. Fallback Locales: Ensure fallback locales are defined in config/i18n.php:

    'fallbacks' => [
        'fr_CA' => ['fr', 'en'],
        'pt_BR' => ['pt', 'en'],
    ],
    
  2. MO File Paths: Use Laravel’s lang_path() helper for consistency:

    $moReader->readFile(lang_path('fr/translations.mo'));
    
  3. Twig Namespace Collisions: If using both Laravel’s trans

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.
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
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope