IMPORTANT: Under active development. Do not use in production, api might change.
Simple approach to eloquent models translation. There are other packages that provide translation functionality, this is a different approach with some trade-offs. Priority is simplicity.
// TODO: add example database schema here.
- easy to get up running on existing applications
- all eloquent model fields are translatable
- original can be created in any language
- translations can be copied from original
- translations can be easily associated later on
You can install the package via composer:
composer require bruno-fernandes/laravel-multi-language
If you want to set custom column names, publish the config file and override the defaults:
php artisan vendor:publish --provider="BrunoFernandes\LaravelMultiLanguage\LaravelMultiLanguageServiceProvider"
// Import the Translatable trait into the eloquent model
use BrunoFernandes\LaravelMultiLanguage\Translatable;
class Page extends Model
{
use Translatable;
}
// Create a migration to add the required columns to the model's table
// Example:
class AddMultilanguageFieldsToPagesTable extends Migration
{
public function up()
{
Schema::table('pages', function (Blueprint $table) {
// Create columns
$table->string(config('laravel-multi-language.lang_key'), 6)
->default('en')->index()->after('id');
$table->integer(config('laravel-multi-language.foreign_key'))
->unsigned()->nullable()->index()->after('id');
// Create composite unique index to prevent multiple
// records using the same lang key
$table->unique([
config('laravel-multi-language.foreign_key'),
config('laravel-multi-language.lang_key')
]);
});
// TODO: if there are already records on the table, create a migration to update
// all of them and set the lang and the original_id with the correct values
}
}
//
// Usage
//
$page = Page::create(['title' => 'English title']);
$englishPage = $page->translateTo('es', ['title' => 'Spanish title']);
$originalPages = Page::onlyOriginals()->get();
// the package will apply the lang scope by default, so only
// the current locale records are returned (it can be disable in the config file)
$currentLocalePages = Page::get();
// if apply lang global scope is disabled you can use the lang scope as follow:
$enPagesWithTranslations = Page::lang('en')->withTranslations()->get();
// NOTE: always use withTranslations() rather than with('translations) as it is more efficient
// using withTranslations() will exlude the current locale from the translations relationship
// if you would like to remove a global scope for a given query,
// you may use the withoutGlobalScope method as follow:
use BrunoFernandes\LaravelMultiLanguage\Scopes\LangScope;
$allPagesOfAllLocales = Page::withoutGlobalScope(LangScope::class)->get();
// TODO: add usage samples to be added
-
When used with Searchable package global scopes need to be removed and applied manually after the search method is used.
-
when using hasOne relationships, if foreign_key and local_key are not set the LangScope (Global Scope) is applied to the relationship, if the relationship model is not translatable an error is thrown.
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'live_players.original_id' in 'where clause' (SQL: select * from `live_players` where `live_players`.`original_id` in (35) and `live_players`.`deleted_at` is null) (View: /home/vagrant/code/resources/frontend/views/index.blade.php)
// This does not work
class Content extends Model
{
public function livePlayer()
{
return $this->hasOne(LivePlayer::class);
}
}
// This works
class Content extends Model
{
public function livePlayer()
{
return $this->hasOne(LivePlayer::class, 'id', 'live_player_id');
}
}
composer test
Please see CHANGELOG for more information what has changed recently.
Please see CONTRIBUTING for details.
If you discover any security related issues, please email [email protected] instead of using the issue tracker.
The MIT License (MIT). Please see License File for more information.