This package allows you to make eloquent models translatable by using separate columns for each language, e.g. title_nl
and title_en
. This package is heavily inspired by Spatie's spatie/laravel-translatable.
You can install the package via composer:
composer require esign/laravel-underscore-translatable
To make your model translatable you need to use the Esign\UnderscoreTranslatable\UnderscoreTranslatable
trait on the model.
Next up, you should define which fields are translatable by adding a public $translatable
property.
use Esign\UnderscoreTranslatable\UnderscoreTranslatable;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use UnderscoreTranslatable;
public $translatable = ['title'];
}
Your database structure should look like the following:
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title_nl')->nullable();
$table->string('title_fr')->nullable();
$table->string('title_en')->nullable();
});
To retrieve a translation in the current locale you may use the attribute you have defined in the translatable
property. Or you could use the getTranslation
method:
$post->title
$post->getTranslation('title')
To retrieve a translation in a specific locale you may use the fully suffixed attribute or pass the locale to the getTranslation
method:
$post->title_nl
$post->getTranslation('title', 'nl')
To check if a translation exists, you may use the hasTranslation
method:
$post->title_en = 'Your first translation';
$post->title_nl = '';
$post->title_fr = null;
$post->hasTranslation('title', 'en'); // returns true
$post->hasTranslation('title', 'nl'); // returns false
$post->hasTranslation('title', 'fr'); // returns false
In case you do not supply a locale, the current locale will be used.
This package allows you to return the value of an attribute's fallback_locale
defined in the config/app.php
of your application.
The third useFallbackLocale
parameter of the getTranslation
method may be used to control this behaviour:
$post->title_en = 'Your first translation';
$post->title_nl = null;
$post->getTranslation('title', 'nl', true); // returns 'Your first translation'
$post->getTranslation('title', 'nl', false); // returns null
Or you may use dedicated methods for this:
$post->title_en = 'Your first translation';
$post->title_nl = null;
$post->getTranslationWithFallback('title', 'nl'); // returns 'Your first translation'
$post->getTranslationWithoutFallback('title', 'nl'); // returns null
To set the translation for the current locale you may use the attribute you have defined in the translatable
property. Or you could pass it immediately when creating a model:
$post->title = 'Your first translation';
Post::create([
'title' => 'Your first translation',
]);
You may also use the setTranslation
method:
$post->setTranslation('title', 'en', 'Your first translation');
$post->setTranslation('title', 'nl', 'Jouw eerste vertaling');
You could also set multiple translations at once using the setTranslations
method or immediately passing them along when creating a model:
$post->setTranslations('title', [
'en' => 'Your first translation',
'nl' => 'Jouw eerste vertaling',
]);
Post::create([
'title' => [
'en' => 'Your first translation',
'nl' => 'Jouw eerste vertaling',
],
]);
This package does not persist translations to the database, so don't forget to save your model:
$post->setTranslation('title', 'en', 'Your first translation');
$post->save();
You're able to define accessors just like you're used to in Laravel:
public function getTitleAttribute($value): string
{
return ucfirst($value);
}
The same goes for mutators:
public function setTitleAttribute($value, $locale): void
{
$this->attributes['title_' . $locale] = strtolower($value);
}
composer test
The MIT License (MIT). Please see License File for more information.