Skip to content
← Back to projects

Laravel Translatable

A trait to make an Eloquent model hold translations

Logo for laravel-translatable

A trait to make Eloquent models translatable

Latest Version on Packagist MIT Licensed GitHub Workflow Status Total Downloads

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();

#Support us

We invest a lot of resources into creating best in class open source packages. You can support us by buying one of our paid products.

We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on our contact page. We publish all received postcards on our virtual postcard wall.

#Documentation

All documentation is available on our documentation site.

#Testing

composer test

#Contributing

Please see CONTRIBUTING for details.

#Security

If you've found a bug regarding security please mail security@spatie.be instead of using the issue tracker.

#Postcardware

You're free to use this package, but if it makes it to your production environment we highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using.

Our address is: Spatie, Kruikstraat 22, 2018 Antwerp, Belgium.

We publish all received postcards on our company website.

#Credits

We got the idea to store translations as json in a column from Mohamed Said. Parts of the readme of his multilingual package were used in this readme.

#Alternatives

#License

The MIT License (MIT). Please see License File for more information.

New version available.