gboquizosanchez / icu-i18n
Advanced ICU Translation support for Laravel with regional fallback strategies.
Installs: 1
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/gboquizosanchez/icu-i18n
Requires
- php: ^8.3
- ext-intl: *
- illuminate/support: ^11.0|^12.0
- illuminate/translation: ^11.0|^12.0
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- hermes/dependencies: ^1.2
- larastan/larastan: ^3.0
- laravel/pint: ^1.14
- nunomaduro/collision: ^8.8
- orchestra/testbench: ^10.0.0||^9.0.0
- pestphp/pest: ^4.0
- pestphp/pest-plugin-arch: ^4.0
- pestphp/pest-plugin-laravel: ^4.0
- phpstan/extension-installer: ^1.4
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-phpunit: ^2.0
- spatie/laravel-ray: ^1.35
README
Advanced Internationalization support for Laravel.
This package extends the native Laravel Translator to provide support for ICU MessageFormat (complex plurals, gender selection, localized currency/dates) and implements a smart Regional Locale Fallback strategy to handle vendor packages gracefully.
🚀 Features
- ICU MessageFormat Support: Use standard syntax like
{{count, plural, ...}}or{{gender, select, ...}}directly in your translation files. - Smart Regional Fallback: Automatically degrades specific namespaces or files from a regional locale (e.g.,
es_MX) to a base locale (e.g.,es).- Problem Solved: You want your app to use
es_MXfor currency formatting, but your vendor packages (likelaravel/uiorspatie/permission) only publish translations ines. This package handles that automatically.
- Problem Solved: You want your app to use
- Seamless Integration: Works as a drop-in replacement for
trans(),__(), and@lang. - Native Performance: Uses PHP's native
intlextension andMessageFormatter.
📦 Installation
You can install the package via composer:
composer require vendor/icu-translation
Publish the configuration file:
php artisan vendor:publish --provider="Vendor\IcuTranslation\I18nServiceProvider"
🔧 Configuration
The configuration file config/icu.php controls the Regional Fallback Strategy.
How logic works
When you request a translation (e.g., __('validation.required')) while your app locale is set to Regional (e.g., es_MX), the translator decides whether to use es_MX or fall back to es based on two rules:
- Namespace Allowed list: If the translation namespace is NOT in the
namespaceslist, it falls back to the base language (es). - File Blocklist: If the translation file is in the
fileslist, it forces the base language (es), even if the namespace is allowed listed.
Default Configuration
// config/icu.php return [ 'regionals' => [ /* * Allowed list Namespaces. * These will use the full regional locale (es_MX). * '*' represents your application's local files (lang/es_MX/...). * Vendor packages are excluded by default to prevent missing translation errors. */ 'namespaces' => [ '*', ], /* * Excluded Files. * These will ALWAYS force the base locale (es). * Useful for standard Laravel files that usually come in generic folders. */ 'files' => [ // 'validation', // 'auth', // 'passwords', ], ], ];
📖 Usage
1. ICU MessageFormat
You can use standard ICU syntax in your JSON or PHP translation files.
lang/en/messages.php
return [ 'welcome' => 'Hello, {name}.', 'balance' => 'Your balance is {amount, number, currency}', 'apples' => '{count, plural, =0{No apples} one{one apple} other{# apples}}', ];
In your Blade views:
{{-- Basic variable --}} {{ __('messages.welcome', ['name' => 'John']) }} {{-- Output: Hello, John. --}} {{-- Automatic Currency Formatting (uses app locale) --}} {{ __('messages.balance', ['amount' => 1250.50]) }} {{-- Output (en_US): Your balance is $1,250.50 --}} {{-- Complex Pluralization --}} {{ __('messages.apples', ['count' => 5]) }} {{-- Output: 5 apples --}}
2. Handling Object Parameters
The translator automatically converts DateTime objects to timestamps and objects implementing __toString() to strings before passing them to the ICU formatter.
$user = new User(['name' => 'Alice']); // implements __toString $date = new DateTime('2023-10-01'); echo __('messages.audit', ['user' => $user, 'date' => $date]);
🧩 Regional Fallback Examples
Assume App::setLocale('es_MX').
Scenario A: Application Strings
You have a file lang/en_GB/home.php.
- Config:
namespaces => ['*'] - Call:
__('home.title') - Result: Loads from
en_GB. (Matches*allowed list).
Scenario B: Vendor Package
You use a package courier that only has translations in lang/vendor/courier/es/messages.php.
- Config:
namespaces => ['*'](Does NOT include 'courier') - Call:
__('courier::messages.error') - Result: Loads from
en. (Namespace 'courier' is not allowed listed -> degrades to base locale).
Scenario C: Validation Files
You want to use standard Laravel validation messages which typically exist in lang/en/validation.php, not en_US.
- Config:
files => ['validation'] - Call:
__('validation.required') - Result: Loads from
en. (File 'validation' is blocklisted -> forces base locale).
🧪 Testing
composer test
Getting Help
If you encounter issues:
- Check the logs - Laravel logs may contain helpful error messages
- Verify requirements - Ensure PHP and Laravel versions meet minimum requirements
- Clear cache - Run
php artisan config:clearandphp artisan cache:clear - Open an issue - Report bugs or request features
Contributing
We welcome contributions! Please feel free to:
- 🐛 Report bugs through GitHub issues
- 💡 Suggest features or improvements
- 🔧 Submit pull requests with bug fixes or enhancements
- 📖 Improve documentation or add examples
Credits 🧑💻
- Author: Germán Boquizo Sánchez
- Built with: PHPStan - The powerful PHP static analysis tool
- Framework: Laravel - The PHP framework
- Contributors: View all contributors
📄 License
This package is open-source software licensed under the MIT License.
📦 Dependencies
PHP dependencies 📦
Develop dependencies 🔧
- Hermes Dependencies
- Larastan Larastan
- Laravel Pint
- Nunomaduro Collision
- Orchestra Testbench
- Pestphp Pest
- Pestphp Pest Plugin Arch
- Pestphp Pest Plugin Laravel
- Phpstan Extension Installer
- Phpstan Phpstan Deprecation Rules
- Phpstan Phpstan Phpunit
- Spatie Laravel Ray
Made with ❤️ for the PHP community