Translations
Translatable attributes are JSON columns holding a locale => value map, resolved by the package’s own HasTranslatableAttributes concern — no third-party translation library. On a post they are title, slug, perex, content, meta_title and meta_description; on categories and tags, name and slug.
Writing translations
use RoundlyConsulting\Posts\Facades\Posts;
$post = Posts::draft()
->title('en', 'Hello world')
->title('sk', 'Ahoj svet')
->content('en', '<p>…</p>')
->by($user) // polymorphic author
->save();
// Plain Eloquent works too — edit translations on the model and save:
$post->setTranslation('perex', 'en', 'A short intro');
$post->save();The builder saves through Posts::create(); setTranslation() returns the model and does not save — call save() yourself. Slugs are generated per locale from the title on save (see Slugs).
Reading translations
$post->getTranslation('title', 'sk'); // 'Ahoj svet' (with fallback)
$post->getTranslation('title', 'de', false); // '' — exact locale, no fallback
$post->getTranslations('title'); // ['en' => 'Hello world', 'sk' => 'Ahoj svet']
$post->translate('title'); // current-locale value, with fallback
$post->translate('title', 'sk'); // a given locale, with fallback
$post->title; // same as translate('title')
$post->isTranslatableAttribute('title'); // true
$post->translatableAttributes(); // ['title', 'slug', 'perex', 'content', 'meta_title', 'meta_description']Fallback order
A read with fallback tries, in order:
- the requested locale;
- the fallback locale — the first one set of translatable.fallback_locale (when translatable-for-laravel is configured), posts.locales.fallback and app.fallback_locale; a blank one is not set and passes to the next;
- the lowest-sorting locale that holds a value — a stable choice, independent of the key order the database returns JSON in.
Direct attribute access ($post->title) resolves through this chain unless the model defines an accessor or mutator for the key. Pass false as the third argument of getTranslation() to read one exact locale; it returns '' when that locale is missing.
Show your open-source love
This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.
More ways to support, including cryptoBy donating, you agree to our donation terms.
Want this built into your product?
We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.