Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Translatable Laravel Package

spatie/laravel-translatable

Adds a HasTranslations trait to Eloquent models to store translations as JSON in the same table (no extra tables). Define translatable attributes via PHP attribute or $translatable, then set/get translations per locale and auto-resolve by app locale.

View on GitHub
Deep Wiki
Context7

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.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope
anil/file-picker
broqit/fields-ai