jawabapp/localization
Composer 安装命令:
composer require jawabapp/localization
包简介
A comprehensive, modern Laravel package for managing multilingual applications with database-driven translations, automatic locale detection, and a beautiful admin interface.
关键字:
README 文档
README
A comprehensive, modern Laravel package for managing multilingual applications with database-driven translations, automatic locale detection, and a beautiful admin interface. Built for Laravel 10+ with full support for the latest language directory structure.
✨ Features
- 🌐 12+ Languages: Pre-configured support for major world languages
- 🎯 Smart Locale Detection: Browser, URL, session, and cookie-based detection
- 📁 Modern Laravel Compatibility: Laravel 10/11
lang/directory structure - 🗂️ Dual Format Support: Both PHP arrays and JSON translations
- 🗃️ Database-Driven Translations: Store translations in database with file fallback
- 🎛️ Professional Admin Interface: Beautiful Tailwind CSS interface
- ⚡ Performance Optimized: Built-in caching and file-based translations
- 🔧 Artisan Commands: CLI tools for import/export and management
- 🛣️ SEO Friendly: Automatic hreflang tags and localized URLs
- 📱 API Support: RESTful API with intelligent locale detection
- 🔄 Hot Reloading: Automatic file export on database changes
- 🔀 Flexible Loading: Database-first with automatic file fallback
📋 Requirements
- PHP: 8.2 or higher
- Laravel: 10.0 or higher
- Extensions: mbstring, json
🚀 Quick Installation
1. Install via Composer
composer require jawabapp/localization
2. Publish Configuration
# Publish config file php artisan vendor:publish --tag=localization-config # Publish and run migrations php artisan vendor:publish --tag=localization-migrations php artisan migrate
3. Configure Middleware
For Laravel 11+, add the middleware to your bootstrap/app.php:
<?php use Illuminate\Foundation\Application; use Illuminate\Foundation\Configuration\Exceptions; use Illuminate\Foundation\Configuration\Middleware; return Application::configure(basePath: dirname(__DIR__)) ->withMiddleware(function (Middleware $middleware): void { // Register localization middleware $middleware->alias([ 'localization' => \Jawabapp\Localization\Http\Middleware\Web\Localization::class, 'localization.web' => \Jawabapp\Localization\Http\Middleware\Web\Localization::class, 'localization.api' => \Jawabapp\Localization\Http\Middleware\Api\Localization::class, ]); }) ->withExceptions(function (Exceptions $exceptions): void { // })->create();
For Laravel 10 and earlier, add the middleware to your app/Http/Kernel.php:
protected $middlewareGroups = [ 'web' => [ // ... other middleware \Jawabapp\Localization\Http\Middleware\Web\Localization::class, ], 'api' => [ // ... other middleware \Jawabapp\Localization\Http\Middleware\Api\Localization::class, ], ];
4. Setup Route Prefixes
Update your App\Providers\RouteServiceProvider.php:
use Jawabapp\Localization\Libraries\Localization; public function boot(): void { // Web routes with locale prefix Route::prefix(Localization::routePrefix()) ->middleware('web') ->group(base_path('routes/web.php')); }
5. Access the Admin Interface
Visit /localization in your browser to manage translations!
🗃️ Database-Driven Translations
The package automatically uses database-driven translations with file fallback. This means:
- ✅ Primary: Translations are loaded from the database first
- ✅ Fallback: If database is unavailable, files are used automatically
- ✅ Performance: Results are cached for optimal performance
- ✅ Flexibility: You can disable database translations if needed
Configuration
Control database translations in config/localization.php:
'database_translations' => [ 'enabled' => true, // Enable database translations 'fallback_to_files' => true, // Fallback to file translations if database fails ],
How It Works
- Translation Request: When you call
__('messages.welcome')ortrans('auth.failed') - Database Check: Package checks the database for the translation first
- File Fallback: If not found in database, loads from
lang/files - Caching: Results are cached to avoid repeated database queries
- Admin Interface: Manage all translations through the web interface at
/localization
Automatic Setup
The database translation system is automatically configured when you install the package:
- 🔧 Auto-Discovery: Laravel automatically registers the
TranslationServiceProvider - 🔄 Seamless Integration: Replaces Laravel's default translator with our enhanced version
- 📊 No Code Changes: Your existing
__()andtrans()calls work unchanged - 🛡️ Safe Fallback: If database fails, translations load from files automatically
Disabling Database Translations
To use only file-based translations, set in your config:
'database_translations' => [ 'enabled' => false, // Disable database translations - use files only ],
⚙️ Configuration
The main configuration file is published to config/localization.php:
<?php return [ // Supported locales 'supported_locales' => ['en', 'ar', 'es', 'fr', 'de'], // Locale detection 'detect_browser_locale' => true, 'store_in_session' => true, 'store_in_cookie' => true, // URL configuration 'url' => [ 'hide_default' => true, // Hide default locale in URLs 'force_locale_in_url' => false, ], // Cache settings 'cache' => [ 'enabled' => true, 'duration' => 60 * 24, // 24 hours ], // Translation groups 'translation_groups' => [ 'auth', 'validation', 'general', 'messages' ], ];
Available Locales
The package comes pre-configured with these locales:
| Code | Language | Native Name |
|---|---|---|
en |
English | English |
ar |
Arabic | العربية |
es |
Spanish | Español |
fr |
French | Français |
de |
German | Deutsch |
it |
Italian | Italiano |
pt |
Portuguese | Português |
ru |
Russian | Русский |
zh |
Chinese | 中文 |
ja |
Japanese | 日本語 |
ko |
Korean | 한국어 |
tr |
Turkish | Türkçe |
📖 Usage Guide
Basic Translation Management
Use Laravel's built-in translation functions:
// In controllers or views echo __('messages.welcome'); echo trans('auth.failed'); echo trans_choice('messages.items', 5); // With parameters echo __('messages.hello', ['name' => 'John']);
Dynamic Locale Switching
use Jawabapp\Localization\Libraries\Localization; // Set locale programmatically Localization::setLocale('fr'); // Get current locale $locale = app()->getLocale(); // Get all supported locales $locales = Localization::getSupportedLocales(); // Get locale native name $name = Localization::getLocaleName('ar'); // Returns: العربية
Working with Localized Routes
Create routes that automatically work with all locales:
Route::localized(function ($locale) { Route::get('/', [HomeController::class, 'index'])->name('home'); Route::get('/about', [AboutController::class, 'index'])->name('about'); Route::get('/products', [ProductController::class, 'index'])->name('products'); });
Generate localized URLs:
// Current locale URL $url = route('products'); // Specific locale URL $url = Route::localizedUrl('products', 'fr'); // Get all locale URLs for hreflang tags $alternateUrls = Localization::getAlternateUrls();
Model Integration
For models with translatable fields, use the _key suffix:
class Post extends Model { protected $fillable = ['title_key', 'content_key', 'slug']; // Accessors for translated content public function getTitleAttribute() { return $this->title_key ? __($this->title_key) : ''; } public function getContentAttribute() { return $this->content_key ? __($this->content_key) : ''; } } // Usage $post = Post::create([ 'title_key' => 'My Blog Post Title', 'content_key' => 'This is the blog post content...', 'slug' => 'my-blog-post' ]);
🎛️ Admin Interface
Access the admin interface at /localization to:
Translation Management
- ✅ View all translations by language and group
- ✅ Add, edit, and delete translations
- ✅ Search and filter translations
- ✅ Bulk operations (delete, export)
- ✅ Visual translation status indicators
Import/Export Tools
- ✅ Export translations to PHP/JSON files
- ✅ Import from existing language files
- ✅ Sync translations between locales
- ✅ Translation statistics and completion rates
Features
- 📱 Responsive Design: Works perfectly on mobile and desktop
- 🎨 Modern UI: Beautiful Tailwind CSS interface
- ⚡ Real-time Updates: Live search and filtering
- 🔄 Batch Operations: Handle multiple translations at once
🔧 Artisan Commands
The package includes powerful CLI commands:
Export Translations
# Export all translations php artisan localization:export # Export specific locale php artisan localization:export --locale=fr # Export specific group php artisan localization:export --locale=en --group=auth # Export only JSON format php artisan localization:export --format=json
Import Translations
# Import all translations from files php artisan localization:import # Import specific locale php artisan localization:import --locale=fr # Overwrite existing translations php artisan localization:import --overwrite
Sync Between Locales
# Sync missing translations from English to French php artisan localization:sync --from=en --to=fr --missing-only # Copy all translations (overwrite existing) php artisan localization:sync --from=en --to=de --overwrite
Cache Management
# Clear translation cache php artisan localization:clear-cache # Clear cache for specific locale php artisan localization:clear-cache --locale=fr
🌐 API Usage
The package provides full API support with intelligent locale detection:
Request Headers
# Custom headers curl -H "X-Localization: fr" /api/endpoint curl -H "X-Locale: es" /api/endpoint # Standard Accept-Language header curl -H "Accept-Language: fr,en;q=0.8" /api/endpoint
Query Parameters
curl /api/endpoint?locale=fr
Response Headers
The API middleware automatically adds:
Content-Language: frheader to responses- Proper locale detection from multiple sources
🗂️ File Structure
The package supports Laravel's modern language directory structure:
lang/
├── en/
│ ├── auth.php
│ ├── validation.php
│ └── messages.php
├── fr/
│ ├── auth.php
│ └── validation.php
├── ar/
│ └── messages.php
├── en.json
├── fr.json
└── ar.json
File Types
- PHP Files (
lang/{locale}/group.php): Structured translations with nested arrays - JSON Files (
lang/{locale}.json): Simple key-value translations
🔍 SEO Features
Automatic Hreflang Tags
Add to your layout:
@foreach(Localization::getAlternateUrls() as $locale => $url) <link rel="alternate" hreflang="{{ $locale }}" href="{{ $url }}" /> @endforeach
Localized URLs
// Generates: /en/products or /products (if default) Route::get('/products', [ProductController::class, 'index'])->name('products');
⚡ Performance Optimization
Caching
Translations are automatically cached:
// Cache keys: // localization.{locale} - All translations for locale // localization.{locale}.{group} - Specific group translations
Static File Export
Export to static files for optimal performance:
php artisan localization:export
Static files load faster than database queries and are automatically cached by Laravel.
🔧 Advanced Configuration
Custom Database Connection
'database' => [ 'connection' => 'translations_db', 'table' => 'app_translations', ],
Custom Translation Groups
'translation_groups' => [ 'auth', 'validation', 'emails', 'custom_module', 'product_catalog' ],
Middleware Configuration
'routes' => [ 'enabled' => true, 'prefix' => 'admin/localization', // Custom admin path 'middleware' => ['web', 'auth', 'admin'], ],
📚 Examples
Complete Laravel Application Setup
- Install and Configure:
composer require jawabapp/localization php artisan vendor:publish --tag=localization-config php artisan migrate
- Create Localized Routes:
// routes/web.php Route::localized(function ($locale) { Route::get('/', function () { return view('welcome'); })->name('home'); Route::get('/products', function () { return view('products.index'); })->name('products'); Route::get('/contact', function () { return view('contact'); })->name('contact'); });
- Add Language Switcher:
<!-- resources/views/layouts/app.blade.php --> <div class="language-switcher"> @foreach(Localization::getSupportedLocales() as $locale) <a href="{{ Route::localizedUrl(Route::currentRouteName(), $locale) }}" class="{{ app()->getLocale() === $locale ? 'active' : '' }}"> {{ Localization::getLocaleName($locale) }} </a> @endforeach </div>
- Use Translations in Views:
<!-- resources/views/welcome.blade.php --> <h1>{{ __('messages.welcome') }}</h1> <p>{{ __('messages.description', ['app' => config('app.name')]) }}</p>
API Integration
// app/Http/Controllers/Api/ProductController.php class ProductController extends Controller { public function index(Request $request) { // Locale is automatically set by middleware $locale = app()->getLocale(); $products = Product::select([ 'id', 'name_key', 'description_key', 'price' ])->get()->map(function ($product) { return [ 'id' => $product->id, 'name' => __($product->name_key), 'description' => __($product->description_key), 'price' => $product->price, ]; }); return response()->json($products); } }
🐛 Troubleshooting
Common Issues
1. Translations not loading
# Clear cache and regenerate
php artisan localization:clear-cache
php artisan localization:export
2. Middleware not working (Laravel 11)
// Ensure middleware is registered in bootstrap/app.php $middleware->alias([ 'localization' => \Jawabapp\Localization\Http\Middleware\Web\Localization::class, ]);
2b. Middleware not working (Laravel 10 and earlier)
// Ensure middleware is registered in Kernel.php \Jawabapp\Localization\Http\Middleware\Web\Localization::class,
3. Routes not found
// Make sure RouteServiceProvider is configured Route::prefix(Localization::routePrefix()) ->middleware('web') ->group(base_path('routes/web.php'));
4. Admin interface 404
# Check if routes are enabled 'routes' => ['enabled' => true]
5. "Call to a member function total() on array" error
# This error occurs when the layout expects paginated data but receives an array # The fix is included in the updated controller - no action needed for users
6. "Class Jawabapp\Localization\Libraries\Localization not found" error
# This error occurs when trying to update translations # The fix is included in the updated controller - no action needed for users
7. Export functionality not working
# If Artisan commands don't work from web interface, try from command line: php artisan localization:export # The web interface now includes direct export functionality as fallback
8. "SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint failed: translations.key"
# This occurs when translation key parsing fails # Ensure your translations have proper namespace, group, and key structure # The updated controller handles this automatically
Debug Mode
Enable debug logging:
'fallback' => [ 'log_missing' => env('APP_DEBUG', false), ],
Performance Issues
# Enable caching php artisan config:cache # Export translations to static files php artisan localization:export
🔄 Upgrading from v1.x
The package uses a new database schema:
- Backup translations:
php artisan localization:export
- Run migration:
php artisan migrate
- Verify data:
The migration automatically converts
language_code→localeand extracts groups from keys.
🤝 Contributing
We welcome contributions! Please see CONTRIBUTING.md for details.
Development Setup
# Clone repository git clone https://github.com/jawabapp/localization cd localization # Install dependencies composer install npm install # Run tests composer test
🔐 Security
If you discover security vulnerabilities, please email i.qanah@gmail.com instead of using the issue tracker.
📜 License
This package is open-sourced software licensed under the MIT license.
👨💻 Credits
- Ibraheem Qanah - Creator & Maintainer
- All Contributors - Thank you!
🌟 Support
- ⭐ Star this repo if it helped you!
- 🐛 Report bugs
- 💡 Request features
- 📖 Documentation
Made with ❤️ for the Laravel community
统计信息
- 总下载量: 21
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 1
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2022-05-29