novius/laravel-translatable
Make Laravel Eloquent models translatable using locale and locale_parent_id. Includes migration macro, Translatable trait, relations for translations (with/without soft-deleted), translate() and getTranslation(), plus withLocale() query scope. Supports Laravel 10–13, PHP 8.2–8.5.
Pros:
locale, locale_parent_id) for translations, avoiding complex joins or pivot tables.withTranslations), scopes (withLocale), and direct access (getTranslation()).translatable() macro for schema migrations, ensuring consistency.Cons:
title length per language).locale and locale_parent_id for performance (not enforced by the package).Cache::remember) for performance-critical applications.| Risk Area | Severity | Mitigation Strategy |
|---|---|---|
| Table bloat | High | Monitor row count; implement archiving or sharding for large datasets. |
| Query performance | Medium | Add indexes on locale and locale_parent_id; test with EXPLAIN for complex queries. |
| Locale management | Medium | Enforce locale validation in AppServiceProvider; document fallback rules. |
| AGPL license | High | Evaluate alternatives (e.g., spatie/laravel-translatable) if AGPL is incompatible. |
| No translation history | Medium | Pair with laravel-auditing or implement custom versioning. |
| Soft delete conflicts | Medium | Override trait methods to handle cascading deletes or use translationsWithDeleted. |
translations table.en, return null, or use user preferences)?locale? If so, ensure proper indexing and test with EXPLAIN.spatie/laravel-translatable (MIT license, separate table, more features) or knuckleswtf/translatable?post.comments[].reply) require custom logic.spatie/laravel-translatable.Post, Product, Page).SELECT * FROM posts WHERE locale = 'fr').locale (string, indexed) and locale_parent_id (unsignedBigInteger, nullable) to target tables.translatable() macro in migrations:
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->translatable(); // Adds locale and locale_parent_id
$table->string('title');
$table->text('content');
$table->timestamps();
});
Translatable trait to models:
use Novius\LaravelTranslatable\Traits\Translatable;
class Post extends Model {
use Translatable;
protected $translatable = ['title', 'content'];
}
translatableConfig(), translateAttributes()).// Example: Set default locale for existing records
Post::whereNull('locale')->update(['locale' => 'en', 'locale_parent_id' => \DB::raw('id')]);
fr translation for an en post).getTranslation('it')).locale_parent_id).created, updated).PostResource::withoutWrapping() for nested translations).Cache::remember('post:1:fr', ...)).BlogPost, Page).Product, Category) with monitoring.['en', 'fr', 'es']).en if fr is missing).title and description").translatableConfig()).WHERE locale_parent_id = ? vs. WHERE id = ?).How can I help you explore Laravel packages today?