Making Eloquent models translatable

Fevrok, the website that I created, at one day I decided to add multi-languages. and that what I exactly did by creating a new translation table for every table that I wanna translate but A downside is that all translations are stored in separate tables. This means that you need to migrate two tables and manage two models.
So I decided to make a package that stores all translations in one table and that’s what I did, the package is now available on Github under the name Tarjama which simply means translation in English

Current working model

Laravel Tarjama Working Model

Installation

You can install the package via composer:

composer require laravelarab/tarjama

If you have Laravel 5.5 and up The package will automatically register itself.

else you have to add the service provider to app/config/app.php

LaravelArab\Tarjama\TarjamaServiceProvider::class,

If you want to change the default locale, you must publish the config file:

php artisan vendor:publish --provider="LaravelArab\Tarjama\TarjamaServiceProvider"

This is the contents of the published file:

return [

/**
* Default Locale || Root columns locale
* We will use this locale if config('app.locale') translation not exist
*/
'locale' => 'en',

/**
* Supported Locales e.g: ['en', 'fr', 'ar']
*/
'locales' => ['ar', 'en', 'fr']

];

next migrate translations table

php artisan migrate

Making a model translatable

The required steps to make a model translatable are:

  • Just use the LaravelArab\Tarjama\Translatable trait.

Here’s an example of a prepared model:

use Illuminate\Database\Eloquent\Model;
use LaravelArab\Tarjama\Translatable;class Item extends Model
{
use Translatable;

/**
* The attributes that are Translatable.
*
* @var array
*/
protected $translatable = [
'name', 'color'
];
}

Available methods

Saving translations

$item = new Item;
$data = array('en' => 'car', 'ar' => 'سيارة');$item->setTranslations('name', $data); // setTranslations($attribute, array $translations, $save = false)// or save one translation
$item->setTranslation('name', 'en', 'car', true); // setTranslation($attribute, $locale, $value, $save = false)// or just do
$item->name = 'car'; // note: this will save automaticaly unless it's the default locale// save if current locale == default locale OR $save = false
$item->save();

Get translations

$item = new Item::first();
// get current locale translation
$item->city
OR
$item->getTranslation('city');// pass translation locales
$item->getTranslation('city', 'ar'); // getTranslation($attribute, $language = null, $fallback = true)
$item->getTranslationsOf('name', ['ar', 'en']); // getTranslationsOf($attribute, array $languages = null, $fallback = true)

Delete translations

$item = new Item::first();
$item->deleteTranslations(['name', 'color'], ['ar', 'en']); // deleteTranslations(array $attributes, $locales = null)

Workarounds

If you are creating a new entry to your translatable model and the current locale !== to default locale for example:

use LaravelArab\Tarjama\Translatable;

class Item
{
use Translatable;

protected $fillable = ['name', 'color'];
protected $translatable = ['name'];
}
$item = new Item;
$item->setTranslation(
'name', // translatable column name
config('tarjama.locale'), // default locale
$request->name // value
);
$item->color = $request->color;
$item->save();
// after saving than create the translation
if (config('app.locale') != config('tarjama.locale')) {
$item->name = $request->name;
} // and your done