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 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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky