upon / mlang
Multilanguage package working for large databases, and fast response
Requires
- php: ^8.3
- ext-filter: *
- illuminate/database: ^v11.44.7|12.*
- illuminate/support: ^v11.44.7|12.*
This package is auto-updated.
Last update: 2025-06-04 16:16:47 UTC
README
This package is a high-performance solution designed to provide efficient multi-language support for Laravel applications. It offers robust features and optimizations to ensure fast and reliable language management, making your application accessible to a global audience without sacrificing performance.
Version Compatibility
This package follows Laravel's major versioning for compatibility.
Package Version | Supported Laravel Versions | PHP Requirements | Architecture |
---|---|---|---|
^1.0 |
Laravel 10.x | PHP >= 8.1 | Model inheritance approach |
^2.0 |
Laravel 11.x, 12.x | PHP >= 8.3 | Trait and interface approach |
Note: If you are using Laravel 11 or 12, please use version
^2.0
of this package.
For Laravel 10, continue using version^1.0
.The architecture has changed between versions - v1 uses model inheritance while v2 uses traits and interfaces.
Features
- Accelerated translation retrieval: Translation strings are efficiently retrieved from the same database table, minimizing database join queries and improving response times.
- Seamless integration with Laravel: The package integrates seamlessly with Laravel, leveraging its existing localization infrastructure while providing performance enhancements.
- Translation helpers: Helper functions and methods to translate your application's content into different languages.
- Language detection: Automatic language detection based on user's browser settings or manual language selection.
- Language fallbacks: Fallback support for missing translations to ensure users always see content in a supported language.
- Smart database structure: Custom columns for efficient language identification and relation management.
- Robust error handling: Intelligent error prevention when columns don't exist or when database operations aren't ready.
- Safe factory integration: Designed to work safely with factories even before migrations run.
- Smooth console integration: Terminal-friendly command output directly in your console.
- Flexible architecture:
- Version 1: Model inheritance approach for simplicity
- Version 2: Trait-based approach for more flexibility and compatibility with existing inheritance hierarchies
- Facade Support: Fluent facade interface for accessing MLang functionality directly
Database Structure
This package adds two essential columns to the models you specify:
- row_id: This column serves as the primary relation key across all languages, linking translations together.
- iso: This column holds the language code (e.g., en, fr, nl), identifying which language each record represents.
Requirements
- PHP >= 8.1 for version 1.x
- PHP >= 8.3 for version 2.x
- Laravel >= 10.0
This package requires the following dependency:
composer require doctrine/dbal
Installation
- Install the package using Composer:
composer require upon/mlang
- Publish the package configuration and language files:
php artisan vendor:publish --tag="mlang"
-
Configure the package by modifying the
config/mlang.php
file according to your requirements. You can specify:- Supported locales
- Default locale
- Translatable models
- Auto-generation settings
- Auto-migration hooks
- Observer behavior
-
Configure your models in the mlang config file:
// config/mlang.php 'models' => [ \App\Models\Category::class, \App\Models\Product::class, // Add all translatable models ]
- Use MLang in your models:
For Version 1.x:
Extend your models with MlangModel
instead of the default Eloquent Model:
<?php // ... use Upon\Mlang\Models\MlangModel; class Category extends MlangModel { // ... }
For Version 2.x: Use the trait and implement the interface instead of extending the model:
<?php // ... use Illuminate\Database\Eloquent\Model; use Upon\Mlang\Contracts\MlangContractInterface; use Upon\Mlang\Models\Traits\MlangTrait; class Category extends Model implements MlangContractInterface { use MlangTrait; // ... }
- Run the migration command to add the required columns to your models:
php artisan mlang:migrate
Using the Facade
MLang comes with a powerful facade that provides a fluent interface for interacting with the package. After installation, you can use the facade as follows:
use Upon\Mlang\Facades\Mlang; use App\Models\Category; // Specify which model to work with Mlang::forModel(Category::class)->migrate(); // Chain multiple operations together Mlang::forModel(Category::class) ->migrate() ->generate(); // Get model information $modelName = Mlang::forModel(Category::class)->getModelName(); // Returns "Category" $tableName = Mlang::forModel(Category::class)->getTableName(); // Returns the table name // You can also use a model instance $category = new Category(); Mlang::forModel($category)->generate();
Configuration Options
The package offers various configuration options to fine-tune its behavior:
// config/mlang.php // Control automatic generation of translations 'auto_generate' => false, // Enable automatic migration after Laravel migrations 'auto_migrate' => false, // Control observer behavior during console operations 'observe_during_console' => false, // Auto-generate translations after seeding 'auto_generate_after_seed' => false, // Specify which models to process after migrations/seeding 'auto_generate_models' => 'all', // Control rollback behavior 'auto_rollback' => true, // Toggle debug output 'debug_output' => true,
Working with Factories
The package is designed to work safely with factories even before migrations have run. It intelligently detects when MLang columns don't exist and avoids trying to use them in such cases.
To ensure smooth operation with factories:
- Set
'auto_generate' => false
in your config file when using factories before migrations. - The trait will automatically detect missing columns and adjust behavior accordingly.
- After running migrations, you can enable auto-generation features.
Version 2.x additional benefits: The trait-based approach in version 2 makes it even easier to work with factories before migrations, as it has enhanced column existence detection and more graceful fallbacks.
Managing Translations
Using Artisan Commands
Generate translations for all models:
php artisan mlang:generate
Generate translations for a specific model:
php artisan mlang:generate {model} # Example: php artisan mlang:generate Category # Or for nested models: php artisan mlang:generate Shop\\Product
Generate for a specific language:
php artisan mlang:generate {model|all} {locale} # Example: php artisan mlang:generate all fr
Remove a language from a table:
php artisan mlang:remove {table} {locale}
# Example: php artisan mlang:remove categories fr
Using the Facade
You can also manage translations programmatically using the facade:
use Upon\Mlang\Facades\Mlang; use App\Models\Category; // Generate translations for a specific model Mlang::forModel(Category::class)->generate(); // Generate translations for a specific model and language Mlang::generate('Category', 'fr'); // Run migrations for a specific model Mlang::forModel(Category::class)->migrate(); // Roll back migrations for a specific model Mlang::forModel(Category::class)->rollback();
Language Detection
To automatically detect the user's browser language:
- Add the locale middleware to your
app/Http/Kernel.php
file:
protected $middlewareGroups = [ 'web' => [ // ... \Upon\Mlang\Middleware\DetectUserLanguageMiddleware::class, ], // ... ];
To manually set the language:
app()->setLocale('fr');
Query Usage
Both package versions provide the same query methods for working with multilingual content:
Finding Records
To find a record by ID, translated to the current application language:
// Returns the record in the current language $category = Category::trFind(1);
Querying with Conditions
To query with conditions while respecting language context:
// Gets a collection in the current language $categories = Category::trWhere(['name' => 'test'])->get();
The trWhere
method works like the normal where
but automatically maps id
to row_id
and adds a language condition, allowing you to chain other query methods:
$categories = Category::trWhere('status', 'active') ->orderBy('created_at', 'desc') ->paginate(10);
Route Model Binding
The package enhances Laravel's route model binding to automatically fetch the correct language version:
// routes/web.php Route::get('/categories/{category}', function (Category $category) { // $category will be in the current application language return view('categories.show', compact('category')); });
Understanding Interface and Trait Relationship
When implementing MLang v2.x in your models, it's important to understand the relationship between the interface and trait:
-
The Interface (
MlangContractInterface
) defines the contract that your models must fulfill to be MLang-compatible. -
The Trait (
MlangTrait
) provides the actual implementation of the methods required by the interface.
You must use both together:
class Category extends Model implements MlangContractInterface { use MlangTrait; // Your model code... }
This provides several benefits:
- Contract Enforcement: Ensures all required methods are available
- Implementation Reuse: Reuses code through the trait
- Flexibility: Allows customization by overriding trait methods
- Type Safety: Provides better IDE support and static analysis
Contributing
Contributions are welcome! If you encounter any issues, have suggestions, or want to contribute to the package, please create an issue or submit a pull request on the package's GitHub repository.
License
This package is open-source software licensed under the MIT license. Feel free to use, modify, and distribute it as per the terms of the license.
Credits
This package was developed by Reymon Zakhary. Special thanks to the Laravel community for their support and inspiration.
Contact
If you have any questions or need further assistance, you can reach out to the package maintainer at reymon@charisma-design.eu.