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 Underscore Translatable Laravel Package

esign/laravel-underscore-translatable

View on GitHub
Deep Wiki
Context7

Make Eloquent models translatable

Latest Version on Packagist Total Downloads GitHub Actions

This package allows you to make eloquent models translatable by using separate columns for each language, e.g. title_nl and title_en. This package is heavily inspired by Spatie's spatie/laravel-translatable.

Installation

You can install the package via composer:

composer require esign/laravel-underscore-translatable

Usage

Preparing your model

To make your model translatable you need to use the Esign\UnderscoreTranslatable\UnderscoreTranslatable trait on the model. Next up, you should define which fields are translatable by adding a public $translatable property.

use Esign\UnderscoreTranslatable\UnderscoreTranslatable;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use UnderscoreTranslatable;

    public $translatable = ['title'];
}

Your database structure should look like the following:

Schema::create('posts', function (Blueprint $table) {
    $table->id();
    $table->string('title_nl')->nullable();
    $table->string('title_fr')->nullable();
    $table->string('title_en')->nullable();
});

Retrieving translations

To retrieve a translation in the current locale you may use the attribute you have defined in the translatable property. Or you could use the getTranslation method:

$post->title
$post->getTranslation('title')

To retrieve a translation in a specific locale you may use the fully suffixed attribute or pass the locale to the getTranslation method:

$post->title_nl
$post->getTranslation('title', 'nl')

To retrieve all translations, you may use getTranslations:

$post->getTranslations('title');
// returns ['en' => 'Your first translation', 'nl' => 'Jouw eerste vertaling']

If you omit the key, translations for all translatable attributes will be returned:

$post->getTranslations();
// returns ['title' => ['en' => '...', 'nl' => '...']]

You may also limit the returned locales:

$post->getTranslations('title', ['en']);
// returns ['en' => 'Your first translation']

To check if a translation exists, you may use the hasTranslation method:

$post->title_en = 'Your first translation';
$post->title_nl = '';
$post->title_fr = null;

$post->hasTranslation('title', 'en'); // returns true
$post->hasTranslation('title', 'nl'); // returns false
$post->hasTranslation('title', 'fr'); // returns false

To retrieve only the locales that have a translated column present for a specific key, use getTranslatedLocales:

$post->title_en = 'Your first translation';
$post->title_nl = 'Jouw eerste vertaling';

$post->getTranslatedLocales('title'); // returns ['en', 'nl']

In case you do not supply a locale, the current locale will be used.

Using a fallback

This package allows you to return the value of an attribute's fallback_locale defined in the config/app.php of your application.

The third useFallbackLocale parameter of the getTranslation method may be used to control this behaviour:

$post->title_en = 'Your first translation';
$post->title_nl = null;
$post->getTranslation('title', 'nl', true); // returns 'Your first translation'
$post->getTranslation('title', 'nl', false); // returns null

Or you may use dedicated methods for this:

$post->title_en = 'Your first translation';
$post->title_nl = null;
$post->getTranslationWithFallback('title', 'nl'); // returns 'Your first translation'
$post->getTranslationWithoutFallback('title', 'nl'); // returns null

Setting translations

To set the translation for the current locale you may use the attribute you have defined in the translatable property. Or you could pass it immediately when creating a model:

$post->title = 'Your first translation';

Post::create([
    'title' => 'Your first translation',
]);

You may also use the setTranslation method:

$post->setTranslation('title', 'en', 'Your first translation');
$post->setTranslation('title', 'nl', 'Jouw eerste vertaling');

You could also set multiple translations at once using the setTranslations method or immediately passing them along when creating a model:

$post->setTranslations('title', [
    'en' => 'Your first translation',
    'nl' => 'Jouw eerste vertaling',
]);

Post::create([
    'title' => [
        'en' => 'Your first translation',
        'nl' => 'Jouw eerste vertaling',
    ],
]);

This package does not persist translations to the database, so don't forget to save your model:

$post->setTranslation('title', 'en', 'Your first translation');
$post->save();

Defining accessors and mutators

You're able to define accessors just like you're used to in Laravel:

public function getTitleAttribute($value): string
{
    return ucfirst($value);
}

The same goes for mutators:

public function setTitleAttribute($value, $locale): void
{
    $this->attributes['title_' . $locale] = strtolower($value);
}

Testing

composer test

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.
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
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