Skip to main content

Black Friday 2025! Only until December 1st: coupon FRIDAY25 for 40% off Yearly/Lifetime membership!

Read more here

astrotomic/laravel-translatable

Premium
9 min read

This package relies on a separate DB table to contain all of your localized model information. You will have to manually create this table and add the necessary columns. The package will then automatically handle the rest.

In other words, it requires more setup initially but provides a lot of flexibility.


Installation

In the full installation guide we can quickly spot that it's not too complicated to install this package:

Installing package via composer:

composer require astrotomic/laravel-translatable

Publishing the config file:

php artisan vendor:publish --tag=translatable

Adapting the configuration file to our case:

'locales' => [
'en',
'es',
],

This will set the base up for us to use.


Usage

After the initial setup, we have to adapt our Models to use the translation, which will require quite a bit of coding (but it's not too complicated).

Use this package, the biggest difference is in Migrations and Models:...

The Full Lesson is Only for Premium Members

Want to access all of our courses? (29 h 14 min)

You also get:

54 courses
Premium tutorials
Access to repositories
Private Discord
Get Premium for $129/year or $29/month

Already a member? Login here

Comments & Discussion

O
Oleksandr ✓ Link copied!

I would also like to add a tip for validation rules. This package has a helper for their convenient creation. It is described here.

For example, I have global function for that

function lang_rules(array $rules): array
{
  return RuleFactory::make($rules);
}

and in form request

public function rules(): array
{
  return lang_rules([
    'publish_date' => ['nullable', 'date'],

    '{title}' => ['required', 'string', 'max:255'],
    '{body}' => ['required', 'string'],
  ]);
}

with this config options

'rule_factory' => [
    'format' => \Astrotomic\Translatable\Validation\RuleFactory::FORMAT_ARRAY,
    'prefix' => '{',
    'suffix' => '}',
]
C
Cedasie ✓ Link copied!

Hello, How can I pluck translation model like Blog (title) / BlogTranslation (title_trans)

public function edit(Post $post)
{
    $blog = Blog::pluck('title', "title_trans", 'id');  <- ??? 

    return view('posts.edit', compact('post', 'blog'));
}
M
Modestas ✓ Link copied!

If I'm not mistaken, you can just do:

Blog::pluck('title', 'id');

And it should work, as it overrides the Title with a translated value automatically

O
Oleksandr ✓ Link copied!

Hi. For such cases I have next trait. It

Blog::joinTranslations()->pluck('title', 'id');
trait WithTranslationsTrait
{
    public function scopeWithTranslations(Builder $query): Builder
    {
        return $query->with([
            'translations' => function ($query) {
                $query->where('locale', app()->getLocale());
            },
        ]);
    }

    public function scopeJoinTranslations(
        Builder $query,
        ?string $modelTable = null,
        ?string $translationsTable = null,
        ?string $modelTableKey = null,
        ?string $translationsTableKey = null
    ): Builder {
        if (!$modelTable) {
            $modelTable = $this->getTable();
        }

        $singularModelTable = Str::singular($modelTable);

        if (!$translationsTable) {
            $translationsTable = $singularModelTable . "_translations";
        }

        $translationsTableKey = (empty($translationsTableKey) ? $singularModelTable . "_id" : $translationsTableKey);
        $modelTableKey = (empty($modelTableKey) ? "id" : $modelTableKey);

        return $query->leftJoin(
            $translationsTable,
            function ($join) use ($modelTable, $translationsTable, $translationsTableKey, $modelTableKey) {
                $join->on("{$translationsTable}.{$translationsTableKey}", '=', "{$modelTable}.{$modelTableKey}")
                    ->where('locale', '=', app()->getLocale());
            }
        );
    }
}
MA
Mahmoud Ahmed ✓ Link copied!

which best to use astrotomic-laravel-translatable or spatie/laravel-translatable

M
Modestas ✓ Link copied!

There is never "a best to use". There is always "the better one for your situation".

In this case, it really depends on how/what your system looks like. Play around with both and see which feels better.