Skip to main content
Back to packages
2,449 GitHub stars

spatie/laravel-translatable

View on GitHub

Description

This package contains a trait to make Eloquent models translatable. Translations are stored as json. There is no extra table needed to hold them.

This package contains a trait HasTranslations to make Eloquent models translatable. Translations are stored as json. There is no extra table needed to hold them.

use Illuminate\Database\Eloquent\Model;
use Spatie\Translatable\Attributes\Translatable;
use Spatie\Translatable\HasTranslations;
 
#[Translatable('name', 'description')]
class NewsItem extends Model
{
use HasTranslations;
 
// ...
}

The attribute accepts a variadic list of column names, so you can pass as many as you need.

Alternatively, you can declare the translatable attributes via a public $translatable property:

use Illuminate\Database\Eloquent\Model;
use Spatie\Translatable\HasTranslations;
 
class NewsItem extends Model
{
use HasTranslations;
 
public $translatable = ['name'];
}

When both the property and the attribute are present, their values are merged and deduplicated.

After the trait is applied on the model you can do these things:

$newsItem = new NewsItem;
$newsItem
->setTranslation('name', 'en', 'Name in English')
->setTranslation('name', 'nl', 'Naam in het Nederlands')
->save();
 
$newsItem->name; // Returns 'Name in English' given that the current app locale is 'en'
$newsItem->getTranslation('name', 'nl'); // returns 'Naam in het Nederlands'
 
app()->setLocale('nl');
$newsItem->name; // Returns 'Naam in het Nederlands'
 
$newsItem->getTranslations('name'); // returns an array of all name translations
 
// You can translate nested keys of a JSON column using the -> notation
// First, add the path to the $translatable array, e.g., 'meta->description'
$newsItem
->setTranslation('meta->description', 'en', 'Description in English')
->setTranslation('meta->description', 'nl', 'Beschrijving in het Nederlands')
->save();
 
$attributeKey = 'meta->description';
$newsItem->$attributeKey; // Returns 'Description in English'
$newsItem->getTranslation('meta->description', 'nl'); // Returns 'Beschrijving in het Nederlands'

Also providing scoped queries for retrieving records based on locales

// Returns all news items with a name in English
NewsItem::whereLocale('name', 'en')->get();
 
// Returns all news items with a name in English or Dutch
NewsItem::whereLocales('name', ['en', 'nl'])->get();
 
// Returns all news items that has name in English with value `Name in English`
NewsItem::query()->whereJsonContainsLocale('name', 'en', 'Name in English')->get();
 
// Returns all news items that has name in English or Dutch with value `Name in English`
NewsItem::query()->whereJsonContainsLocales('name', ['en', 'nl'], 'Name in English')->get();
 
// The last argument is the "operand" which you can tweak to achieve something like this:
 
// Returns all news items that has name in English with value like `Name in...`
NewsItem::query()->whereJsonContainsLocale('name', 'en', 'Name in%', 'like')->get();
 
// Returns all news items that has name in English or Dutch with value like `Name in...`
NewsItem::query()->whereJsonContainsLocales('name', ['en', 'nl'], 'Name in%', 'like')->get();

Related Content on Laravel Daily

Video