Installation
composer require places2be/locales
Add the service provider to config/app.php under providers:
Wirbelwild\Locales\LocalesServiceProvider::class,
Publish Config (Optional)
php artisan vendor:publish --provider="Wirbelwild\Locales\LocalesServiceProvider" --tag="config"
This generates config/locales.php with default country/language mappings.
First Use Case: Fetching Country/Region Data
use Wirbelwild\Locales\Facades\Locales;
// Get country name by code
$countryName = Locales::getCountryName('US'); // "United States"
// Get country code by name
$countryCode = Locales::getCountryCode('Germany'); // "DE"
// Get all countries as an array
$countries = Locales::getCountries();
use Wirbelwild\Locales\Facades\Locales;
$validCountry = Locales::isValidCountryCode('CA'); // true
$invalidCountry = Locales::isValidCountryCode('XX'); // false
use Illuminate\Support\Facades\Validator;
$validator = Validator::make($request->all(), [
'country_code' => 'required|country_code', // Custom rule
]);
Register a custom rule in AppServiceProvider:
Validator::extend('country_code', function ($attribute, $value, $parameters, $validator) {
return Locales::isValidCountryCode($value);
});
$languageCode = app()->getLocale(); // e.g., 'fr_FR'
$languageName = Locales::getLanguageName($languageCode); // "French"
$languageCodeFromName = Locales::getLanguageCode('German'); // 'de_DE'
namespace App\Http\Middleware;
use Wirbelwild\Locales\Facades\Locales;
use Closure;
class SetLocale
{
public function handle($request, Closure $next)
{
$locale = $request->header('Accept-Language') ?? config('app.locale');
if (Locales::isValidLanguageCode($locale)) {
app()->setLocale($locale);
}
return $next($request);
}
}
$user = User::find(1);
$countryData = Locales::getCountryData($user->country_code);
$response = [
'user' => $user,
'country' => $countryData,
];
$users = User::with(['countryData' => function ($query) {
$query->select('id', 'country_code')
->addSelect(function ($query) {
return $query->getQuery()->from('countries')
->selectRaw('name as country_name')
->whereColumn('countries.code', 'users.country_code');
});
}])->get();
// Override country data via config/locales.php
'countries' => [
'US' => 'United States of America (Custom)',
'XX' => 'Custom Region', // Add new entries
],
Locales::setCustomCountries(['XX' => 'Custom Region']);
Locales::setCustomLanguages(['zz' => 'Custom Language']);
Case Sensitivity
'US', not 'us').$countryCode = strtoupper($request->input('country_code'));
Missing Data for New Regions
setCustomCountries() dynamically.Performance with Large Datasets
Locales::getCountries() or Locales::getLanguages() can be slow if called repeatedly.AppServiceProvider:
public function boot()
{
Cache::remember('locales.countries', now()->addHours(1), function () {
return Locales::getCountries();
});
}
Locale vs. Language Code Confusion
getLanguageCode('German') returns 'de_DE' (locale), not just 'de'.getLanguageCode() for full locale or getLanguageCodeShort() (if available) for language-only codes.Dependency on Published Config
config/locales.php for customizations. Forgetting to publish the config will default to hardcoded values.php artisan vendor:publish --provider="Wirbelwild\Locales\LocalesServiceProvider" --tag="config"
Validate Inputs
Use Locales::isValidCountryCode() or Locales::isValidLanguageCode() to debug invalid inputs:
if (!Locales::isValidCountryCode($code)) {
\Log::error("Invalid country code: {$code}");
}
Inspect Data Structure Dump the raw data to understand the package’s internal structure:
dd(Locales::getCountries());
dd(Locales::getLanguages());
Override Methods for Testing
Mock the Locales facade in tests:
$this->partialMock(Wirbelwild\Locales\Facades\Locales::class, function ($mock) {
$mock->shouldReceive('getCountryName')
->with('US')
->andReturn('Mocked USA');
});
Add Custom Regions/Languages Extend the config or use runtime methods:
// Runtime addition
Locales::setCustomCountries(['AB' => 'Custom Country']);
Locales::setCustomLanguages(['ab' => 'Custom Language']);
Create Helper Traits Reuse locale logic across projects:
trait LocaleHelper
{
public function getCountryName(string $code): string
{
return Locales::getCountryName($code);
}
}
Integrate with Eloquent Add accessors to models:
class User extends Model
{
public function getCountryNameAttribute()
{
return Locales::getCountryName($this->country_code);
}
}
Localization in Blade Use the facade directly in views:
<select name="country">
@foreach(Locales::getCountries() as $code => $name)
<option value="{{ $code }}">{{ $name }}</option>
@endforeach
</select>
API Response Formatting Normalize responses with locale data:
return response()->json([
'user' => $user,
'metadata' => [
'country' => Locales::getCountryData($user->country_code),
'language' => Locales::getLanguageData(app()->getLocale()),
],
]);
How can I help you explore Laravel packages today?