Reading and writing
Reading
Property access returns the app locale’s value through the fallback chain; the explicit methods let you pick the locale and switch fallback off:
$topic->name; // localized, fallback chain
$topic->getTranslation('name', 'sk'); // explicit locale, fallback on
$topic->getTranslation('name', 'sk', false); // no fallback -> null if missing
$topic->translatedOrNull('name'); // app locale, NO fallback
$topic->getTranslations('name'); // full map (admin resources)
$topic->getTranslations(); // every translatable attr -> its map
$topic->hasTranslation('name', 'sk'); // bool
$topic->getTranslatedLocales('name'); // list<string>
$topic->missingLocales('name'); // supported - translated (feed an AI service)
$topic->isTranslatableAttribute('name'); // bool
$topic->getTranslatableAttributes(); // list<string>Writing
Setters are fluent and return the model; call save() to persist as usual. Assigning a string writes the app locale’s value, assigning an array replaces the whole map, and a JSON-path key such as update(['name->sk' => …]) patches one locale through the same guards:
$topic->setTranslation('name', 'sk', 'Investovanie'); // fluent, returns $this
$topic->setTranslation('name', 'sk', null); // forgets sk (never stores blank)
$topic->setTranslations('name', ['en' => 'Investing', 'sk' => 'Investovanie']);
$topic->replaceTranslations(['name' => ['en' => 'Investing']]);
$topic->forgetTranslation('name', 'sk');
$topic->forgetAllTranslations('name');
$topic->name = 'Investing'; // sets the APP locale value
$topic->name = ['en' => 'Investing', 'sk' => 'Investovanie']; // replaces the map
$topic->save();
$topic->update(['name->sk' => 'Sporenie']); // JSON-path key: patches one locale, same guardsBlank and null values are dropped, so a map never stores an empty string and the fallback chain always has something real to fall back to. setTranslation(…, null) and forgetTranslation() remove a locale; setTranslations() replaces one field’s entire map, and replaceTranslations() does the same for several fields at once.
Dirty tracking compares the decoded map, not the raw JSON string: PostgreSQL and MySQL hand JSON back re-spaced and key-reordered, yet re-saving an unchanged map issues no UPDATE on any engine.
Method reference
| Method | Returns | Purpose |
|---|---|---|
getTranslation($key, $locale = null, $useFallback = true) | ?string | One locale’s value; defaults to the app locale with fallback on. |
translatedOrNull($key) | ?string | The app locale’s value, no fallback. |
getTranslations($key = null) | array | One field’s map, or every translatable field’s map. |
setTranslation($key, $locale, $value) | static | Set one locale; null or an empty string removes it. |
setTranslations($key, $translations) | static | Replace a field’s whole map. |
replaceTranslations($fields) | static | Replace the maps of several fields at once. |
forgetTranslation($key, $locale) | static | Remove one locale. |
forgetAllTranslations($key) | static | Clear a field’s map. |
hasTranslation($key, $locale = null) | bool | Whether a locale is stored; defaults to the app locale. |
getTranslatedLocales($key) | list<string> | Locales that have a value. |
missingLocales($key) | list<string> | Supported locales without a value. |
isTranslatableAttribute($key) | bool | Whether the attribute is listed in $translatable. |
getTranslatableAttributes() | list<string> | Every listed attribute. |
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.