initiumlv/laravel-translatable
Composer 安装命令:
composer require initiumlv/laravel-translatable
包简介
Laravel package for translatable models
README 文档
README
A Laravel package that provides easy multi-language (i18n) support for Eloquent models. It automatically manages translations by separating translatable columns into dedicated translation tables, allowing you to store and retrieve model data in multiple languages seamlessly.
Features
- Automatic Translation Table Management - Translatable columns are automatically moved to a separate
{table}_translationstable - Eloquent Integration - Use the
HasTranslationstrait for automatic translation joins and locale-aware queries - Schema Builder - Extended schema builder (
TranslatableSchema) for creating and modifying translatable tables - Artisan Commands - Generate migrations, cache translatable columns, and manage translations via CLI
- Multi-Locale Support - Save translations for multiple locales at once
- Performance Caching - Cache translatable columns to avoid database queries
- Laravel 12 Compatible - Built for modern Laravel applications
Requirements
- PHP 8.2+
- Laravel 12.0+
Installation
Install the package via Composer:
composer require initiumlv/laravel-translatable
Publish the configuration file (optional):
php artisan vendor:publish --tag="laravel-translatable-config"
Configuration
The configuration file config/translatable.php contains the following options:
return [ // How to handle missing translations: 'strict', 'nullable', or 'fallback' 'missing_translation_strategy' => 'strict', // Path where translatable column cache will be stored 'cache_path' => 'bootstrap/cache/translatable.php', // Automatically regenerate cache after running migrations 'auto_cache_after_migrate' => true, // Suffix used for translation tables (default: _translations) 'table_suffix' => '_translations', // System columns to exclude when detecting translatable columns 'system_columns' => ['id', 'locale'], ];
Missing Translation Strategies
The missing_translation_strategy option controls how the package handles records without translations in the current locale:
| Strategy | Behavior |
|---|---|
strict |
Default. Only returns records that have a translation in the current locale. Uses INNER JOIN - records without translations are excluded. |
nullable |
Returns all records. Translatable columns will be NULL if no translation exists. Uses LEFT JOIN. |
fallback |
Returns all records. Uses app.fallback_locale translation when current locale doesn't exist. Uses LEFT JOIN with COALESCE. |
Usage
Creating Translatable Tables
Use the TranslatableSchema facade in your migrations to create tables with translatable columns:
<?php use Illuminate\Database\Migrations\Migration; use Initium\LaravelTranslatable\Components\Database\Blueprint; use Initium\LaravelTranslatable\Facades\TranslatableSchema; return new class extends Migration { public function up(): void { TranslatableSchema::create('products', function (Blueprint $table) { $table->id(); // Non-translatable columns (stay in main table) $table->decimal('price', 10, 2)->default(0); $table->boolean('is_active')->default(true); $table->integer('sort_order')->default(0); // Translatable columns (moved to products_translations table) $table->string('name')->translatable(); $table->text('description')->nullable()->translatable(); $table->timestamps(); }); } public function down(): void { TranslatableSchema::dropIfExists('products'); } };
This creates two tables:
products table:
| Column | Type |
|---|---|
| id | bigint |
| price | decimal(10,2) |
| is_active | boolean |
| sort_order | integer |
| created_at | timestamp |
| updated_at | timestamp |
product_translations table:
| Column | Type |
|---|---|
| id | bigint |
| product_id | bigint (foreign key) |
| locale | varchar |
| name | varchar |
| description | text (nullable) |
Adding the Trait to Your Model
Add the HasTranslations trait to your Eloquent model:
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use Initium\LaravelTranslatable\Components\Database\Concerns\HasTranslations; class Product extends Model { use HasTranslations; protected $guarded = []; }
Saving Translations
Save with Current Locale
// Uses app()->getLocale() by default $product = new Product(); $product->price = 99.99; $product->is_active = true; $product->name = 'English Product Name'; $product->description = 'English description'; $product->save();
Save with Specific Locale
$product = new Product(); $product->price = 49.99; $product->name = 'Latvian Product Name'; $product->description = 'Latvian description'; $product->save(locale: 'lv');
Save Multiple Translations at Once
$product = new Product(); $product->price = 99.99; $product->save(); $product->saveTranslations([ 'en' => ['name' => 'English Name', 'description' => 'English description'], 'lv' => ['name' => 'Latvian Name', 'description' => 'Latvian description'], 'de' => ['name' => 'German Name', 'description' => 'German description'], ]);
Retrieving Translations
The HasTranslations trait automatically joins the translation table and filters by the current locale:
// Set the application locale app()->setLocale('en'); // Get product with English translations $product = Product::find(1); echo $product->name; // "English Name" echo $product->description; // "English description" // Switch locale app()->setLocale('lv'); // Get product with Latvian translations $product = Product::find(1); echo $product->name; // "Latvian Name"
Query Without Translation Scope
To retrieve records without the automatic translation join:
// Get all products regardless of translation availability $products = Product::withoutTranslations()->get();
Modifying Translatable Tables
Add New Translatable Columns
TranslatableSchema::table('products', function (Blueprint $table) { $table->string('subtitle')->nullable()->translatable(); });
Modify Existing Translatable Columns
TranslatableSchema::table('products', function (Blueprint $table) { $table->text('description')->nullable()->translatable()->change(); });
Drop Translatable Columns
TranslatableSchema::table('products', function (Blueprint $table) { $table->dropTranslatable('subtitle'); });
Supported Column Types
The following column types can be made translatable:
Text Types:
| Method | Description |
|---|---|
string($column, $length) |
Variable length string |
text($column) |
Large text field |
mediumText($column) |
Medium text field |
longText($column) |
Very large text field |
json($column) |
JSON data |
Numeric Types:
| Method | Description |
|---|---|
integer($column) |
Integer |
tinyInteger($column) |
Tiny integer |
smallInteger($column) |
Small integer |
mediumInteger($column) |
Medium integer |
bigInteger($column) |
Big integer |
unsignedInteger($column) |
Unsigned integer |
unsignedTinyInteger($column) |
Unsigned tiny integer |
unsignedSmallInteger($column) |
Unsigned small integer |
unsignedMediumInteger($column) |
Unsigned medium integer |
unsignedBigInteger($column) |
Unsigned big integer |
decimal($column, $total, $places) |
Decimal with precision |
unsignedDecimal($column, $total, $places) |
Unsigned decimal |
float($column, $precision) |
Floating point |
double($column) |
Double precision |
Other Types:
| Method | Description |
|---|---|
boolean($column) |
Boolean true/false |
All column modifiers work as expected:
$table->string('name', 100)->nullable()->default('Untitled')->translatable(); $table->decimal('local_price', 10, 2)->translatable(); // Price that varies by locale $table->boolean('is_available')->default(true)->translatable(); // Availability per locale
Artisan Commands
Generate Translatable Migration
# Create a new translatable table php artisan make:translatable-migration create_products_table --create=products # Modify an existing translatable table php artisan make:translatable-migration add_subtitle_to_products_table --table=products # Auto-detect table name from migration name php artisan make:translatable-migration create_categories_table
Cache Translatable Columns
Generate a PHP cache file of translatable columns for improved performance:
php artisan translatable:cache
This scans your database for all *_translations tables and creates a cache file mapping tables to their translatable columns.
Clear Cache
Remove the translatable columns cache:
php artisan translatable:clear
API Reference
TranslatableSchema Facade
| Method | Description |
|---|---|
create($table, Closure $callback) |
Create a new translatable table |
table($table, Closure $callback) |
Modify an existing translatable table |
drop($table) |
Drop both main and translation tables |
dropIfExists($table) |
Safely drop both tables if they exist |
hasTable($table) |
Check if table exists |
hasColumn($table, $column) |
Check if column exists |
dropColumns($table, array $columns) |
Drop specific columns |
rename($from, $to) |
Rename table |
connection($name) |
Get builder for specific database connection |
Blueprint Methods
| Method | Description |
|---|---|
translatable() |
Mark column as translatable |
dropTranslatable($columns) |
Drop translatable columns |
getTranslatableColumns() |
Get new translatable columns |
getChangedTranslatableColumns() |
Get modified translatable columns |
getAllTranslatableColumns() |
Get all translatable columns |
hasTranslatableColumns() |
Check if blueprint has translatable columns |
getTranslationTableName() |
Get translation table name |
getTranslationForeignKey() |
Get foreign key name |
HasTranslations Trait Methods
| Method | Description |
|---|---|
getTranslatableAttributes() |
Get array of translatable column names |
getTranslationTableName() |
Get the translation table name |
getTranslationForeignKey() |
Get the foreign key column name |
save(array $options, ?string $locale) |
Save model with optional specific locale |
saveTranslations(array $translations) |
Save translations for multiple locales |
scopeWithoutTranslations($query) |
Query without automatic translation join |
How It Works
-
Column Separation: When you call
->translatable()on a column definition, it's marked for separation from the main table. -
Automatic Table Creation: The
TranslatableSchemaBuilderautomatically creates a{table}_translationstable with the translatable columns, a foreign key reference, and a locale column. -
Global Scope: The
TranslationScopeis automatically applied to models usingHasTranslations, joining the translation table and filtering by the current application locale. -
Atomic Saves: Translation data is saved within database transactions to ensure data consistency.
-
Pending Queue: Translation attribute changes are queued before saving to avoid race conditions when setting multiple translatable attributes.
Testing
composer test
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
License
The MIT License (MIT). Please see License File for more information.
initiumlv/laravel-translatable 适用场景与选型建议
initiumlv/laravel-translatable 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 0 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 02 月 03 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「translatable」 「laravel」 「laravel-translatable」 「initium」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 initiumlv/laravel-translatable 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 initiumlv/laravel-translatable 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 initiumlv/laravel-translatable 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
A Laravel Eloquent model trait for translatable resource
An Astrotomic Translatable extension for Laravel Nova.
Doctrine2 behavior traits - slowhop fork
A Laravel Nova package for translatable fields
A library to extend Object capabilities.
Silverstripe Translatable extension for DataObjects
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 17
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-02-03