Weave 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 Laravel Package

giggsey/locale

Up-to-date Unicode CLDR locale data packaged as native PHP arrays. Created to avoid requiring the PHP intl extension and to provide newer locale data than many operating systems ship. Used primarily by libphonenumber-for-php (GeoCoder support).

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require giggsey/locale
    

    Pin the version (e.g., ^2.9) to avoid auto-updates breaking CLDR structure.

  2. First Usage:

    use Giggsey\Locale\Locale;
    
    $locale = new Locale();
    $countryName = $locale->getCountryName('US', 'en'); // "United States"
    $countries = $locale->getCountries(); // Array of all countries with metadata
    
  3. Laravel Integration: Register as a service provider (optional but recommended):

    // app/Providers/AppServiceProvider.php
    public function register()
    {
        $this->app->singleton('locale', function () {
            return new Locale();
        });
    }
    

    Now use app('locale')->getCountryName('US') anywhere in Laravel.

First Use Case

Dynamic Country Dropdowns: Replace hardcoded country arrays in Blade templates with CLDR data:

<select name="country">
    @foreach(app('locale')->getCountries() as $code => $data)
        <option value="{{ $code }}">
            {{ $data['en']['displayName'] }}
        </option>
    @endforeach
</select>

Implementation Patterns

Core Workflows

  1. Locale-Aware Country Names:

    $locale = new Locale();
    $nameEn = $locale->getCountryName('US', 'en'); // "United States"
    $nameEs = $locale->getCountryName('US', 'es'); // "Estados Unidos"
    
  2. Supported Locales:

    $supportedLocales = $locale->getSupportedLocales(); // ['en', 'es', 'fr', ...]
    
  3. Country Metadata:

    $countryData = $locale->getCountry('US');
    // Returns array with:
    // - 'name': 'United States'
    // - 'region': 'Americas'
    // - 'subregion': 'North America'
    // - 'languages': ['en']
    
  4. Region Filtering:

    $americanCountries = $locale->getCountriesForRegion('019'); // 'Americas' region code
    

Laravel-Specific Patterns

  1. Service Provider Binding:

    // app/Providers/AppServiceProvider.php
    public function boot()
    {
        view()->composer('*', function ($view) {
            $view->with('countries', app('locale')->getCountries());
        });
    }
    

    Now access $countries in all Blade views.

  2. Validation Rules:

    use Illuminate\Validation\Rule;
    
    $validator->addRules([
        'country' => [
            Rule::in(array_keys(app('locale')->getCountries())),
        ],
    ]);
    
  3. API Response Helper:

    // app/Http/Controllers/CountryController.php
    public function index()
    {
        return response()->json([
            'countries' => app('locale')->getCountries(),
        ]);
    }
    
  4. Database Seeding:

    // database/seeders/CountrySeeder.php
    public function run()
    {
        $locale = new Locale();
        foreach ($locale->getCountries() as $code => $data) {
            DB::table('countries')->updateOrCreate(
                ['code' => $code],
                [
                    'name' => $data['en']['displayName'],
                    'native_name' => $data['en']['nativeDisplayName'] ?? null,
                    'region' => $data['region'] ?? null,
                ]
            );
        }
    }
    

Performance Optimization

  1. Caching CLDR Data:

    // Cache for 1 hour
    $cachedCountries = Cache::remember('locale.countries', now()->addHour(), function () {
        return app('locale')->getCountries();
    });
    
  2. Lazy-Loading for Large Apps:

    // Load only countries for a specific region
    $regionCode = '019'; // Americas
    $americanCountries = app('locale')->getCountriesForRegion($regionCode);
    
  3. Frontend Integration:

    // Fetch CLDR data once and cache in Vue/React
    axios.get('/api/locale/countries')
         .then(response => {
             this.countries = response.data;
             cache.set('locale.countries', response.data);
         });
    

Gotchas and Tips

Pitfalls

  1. CLDR Version Locking:

    • Issue: Updating the package may break code if CLDR data structure changes (e.g., new fields, renamed keys).
    • Fix: Pin the version strictly (e.g., 2.9.0) and test thoroughly after updates.
  2. Memory Usage:

    • Issue: Loading all CLDR data (~1-2MB) may impact memory on high-traffic routes.
    • Fix: Cache the data in Redis or load only required subsets (e.g., getCountriesForRegion()).
  3. Locale Fallbacks:

    • Issue: Some locales may not have translations for all countries.
    • Fix: Use a fallback locale (e.g., 'en'):
      $name = $locale->getCountryName('US', 'es', 'en'); // Fallback to English
      
  4. Territory vs. Country:

    • Issue: CLDR distinguishes between countries and territories (e.g., 'BQ' for Bonaire, Sint Eustatius and Saba).
    • Fix: Use getCountries() for all entries or filter by type:
      $countries = array_filter($locale->getCountries(), fn($data) => $data['type'] === 'country');
      
  5. PHP Version Mismatch:

    • Issue: Package requires PHP 8.1+ (since v2.8.0). Older versions may have stale CLDR data.
    • Fix: Downgrade to ^2.0 for PHP 7.2-7.4, but expect outdated CLDR (e.g., v41).

Debugging Tips

  1. Validate CLDR Data:

    $countries = app('locale')->getCountries();
    dd(array_key_exists('US', $countries)); // Debug missing entries
    
  2. Check for Deprecated Methods:

  3. Handle Missing Locales:

    try {
        $name = $locale->getCountryName('ZZ', 'xx'); // Invalid locale
    } catch (\InvalidArgumentException $e) {
        // Fallback logic
    }
    

Extension Points

  1. Custom CLDR Data:

    • Override the default data by extending the Locale class:
      class CustomLocale extends \Giggsey\Locale\Locale
      {
          public function __construct()
          {
              parent::__construct();
              $this->data = array_merge($this->data, $this->customData());
          }
      
          protected function customData()
          {
              return [
                  'XX' => [
                      'en' => ['displayName' => 'Custom Land'],
                      'region' => '000',
                  ],
              ];
          }
      }
      
  2. Add Territory Groups:

    $locale = new Locale();
    $europeanCountries = $locale->getCountriesForRegion('150'); // 'Europe' region code
    
  3. Integrate with libphonenumber-for-php:

    use libphonenumber\PhoneNumberUtil;
    use Giggsey\Locale\Locale;
    
    $phoneUtil = PhoneNumberUtil::getInstance();
    $locale = new Locale();
    
    $phoneNumber = $phoneUtil->parse('+14155552671', 'US');
    $countryName = $locale->getCountryName($phoneUtil->getRegionCode($phoneNumber));
    

Configuration Quirks

  1. Autoloading:

    • Ensure vendor/autoload.php is included in Laravel’s autoloader (handled automatically by Composer).
  2. Composer Build:

    • If you need to rebuild CLDR data (e.g., for custom versions):
      composer run build
      
    • Warning: This overwrites the bundled data. Use sparingly.
  3. Laravel Facade:

    • To create a facade for cleaner syntax:
      php artisan make:facade LocaleFacade
      
      Then update app/Facades/LocaleFacade.php:
      public static function getCountryName($code, $locale = 'en', $fallbackLocale = null)
      {
          return app('locale')->getCountryName($code, $locale, $fallbackLocale);
      }
      
      Now use LocaleFacade::getCountryName('US').

Pro Tips

  1. Seed DB with CLDR Data:
    // database/seeders/Initialize
    
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.
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
adachsoft/php-code-style