elgohr / laravel-trans-builder
A professional UI-based migration builder for Laravel Translatable package
Package info
github.com/AmirElgohr126/laravel-prince-trans
pkg:composer/elgohr/laravel-trans-builder
Requires
- php: ^8.1
- laravel/framework: ^10.0|^11.0|^12.0|^13.0
- livewire/livewire: ^3.0
Suggests
- astrotomic/laravel-translatable: Install this to use generated models with the Translatable trait.
README
A professional UI-based migration builder for Laravel that simplifies creating database tables with full translatable field support using the Astrotomic Laravel Translatable package.
🎯 Features
Core Features
- Visual UI Builder - Intuitive interface to design database tables using a phpMyAdmin-like builder
- Translatable Fields - Seamlessly separate translatable and non-translatable columns
- Automatic Translation Tables - Auto-generates translation tables with proper constraints
- Full Customization - Configure every aspect of your table structure
- Live Preview - Preview generated migration and model code before export
- One-Click Download - Export migration and model files directly
- Generate In Project - Write migration, models, repository files, and seeder directly into your Laravel project
- Artisan Command - Quick access via
php artisan translatable:builder
Advanced Features
- Multiple primary key types (Auto-increment, Big ID, UUID)
- Foreign key management with cascade actions
- Database engine and charset configuration
- Soft deletes support
- Timestamps management
- Custom naming for translation tables and foreign keys
- Column reordering
- Edit/remove columns before generation
- Model generation with Translatable integration
- Repository generation with admin CRUD pattern
- Seeder generation for main and translation tables
📦 Installation
1. Install via Composer
composer require elgohr/laravel-trans-builder
2. Publish Configuration (Optional)
php artisan vendor:publish --tag=translatable-builder-config
3. Requirements
- PHP 8.1+
- Laravel 10.0+
- Livewire 3.0+
Astrotomic Translatable is optional for installation. If installed, generated models include the trait usage automatically.
🚀 Quick Start
Access the Builder
Option 1: Web Route
http://your-app.test/translatable-builder
Option 2: Artisan Command
php artisan translatable:builder
# With auto-serve
php artisan translatable:builder --serve
Basic Workflow
-
Step 1: Basic Configuration
- Enter table name
- Configure primary key, engine, charset
- Set timestamps, soft deletes options
- Customize translation table names (optional)
-
Step 2: Add Columns
- Click "Add Column"
- Configure each column:
- Name, type, length/precision
- Nullable, default values
- Indexes (unique, index)
- Foreign keys
- Mark as "Translatable" ✨
-
Step 3: Preview
- Review generated migration
- Review generated model
- Copy code, download files, or generate directly in project
-
Step 4: Use Generated Files
- Place migration in
database/migrations/ - Place model in
app/Models/ - Run
php artisan migrate
- Place migration in
-
Optional: Generate In Project (Recommended)
- Click
Generate In Projectin Preview - The package generates automatically:
- Migration in
database/migrations - Model folder in
app/Models/{Model} {Model}.php{Model}Translation.php{Model}Repository.php{Model}EloquentRepository/Eloquent{Model}Repository.php{Model}Seeder.phpindatabase/seeders
- Migration in
- Click
🖼️ Interface Screenshots
Table Configuration (Step 1)
Columns Builder (Step 2)
Generated Migration Output
🎨 Usage Examples
Building a Blog System
Table Configuration:
- Table Name:
posts - Timestamps: ✓
- Soft Deletes: ✓
Columns:
user_id(foreignId) →users.idtitle(string, 200) → Translatable ✓slug(string, 200) → Translatable ✓content(text) → Translatable ✓excerpt(text, nullable) → Translatable ✓is_published(boolean, default: false)published_at(dateTime, nullable)view_count(integer, default: 0)
Generated Files:
Migration:
Schema::create('posts', function (Blueprint $table) { $table->id(); $table->foreignId('user_id')->constrained('users')->cascadeOnDelete(); $table->boolean('is_published')->default(false); $table->dateTime('published_at')->nullable(); $table->integer('view_count')->default(0); $table->softDeletes(); $table->timestamps(); }); Schema::create('posts_translations', function (Blueprint $table) { $table->id(); $table->string('title'); $table->string('slug'); $table->text('content'); $table->text('excerpt')->nullable(); $table->string('locale')->index(); $table->unique(['posts_id', 'locale']); $table->foreign('posts_id')->references('id')->on('posts')->cascadeOnDelete(); });
Model:
class Post extends Model { use Translatable; public $translatedAttributes = ['title', 'slug', 'content', 'excerpt']; protected $casts = [ 'is_published' => 'boolean', 'published_at' => 'datetime', 'view_count' => 'integer', ]; public function user() { return $this->belongsTo(User::class); } }
Building a Product Catalog
Table Configuration:
- Table Name:
products - Timestamps: ✓
- Engine: InnoDB
- Charset: utf8mb4
Columns:
sku(string, 100, unique)price(decimal, 10, 2, default: 0)stock(integer, default: 0, nullable)is_active(boolean, default: true)category_id(foreignId) →categories.idname(string, 200) → Translatable ✓description(text) → Translatable ✓slug(string) → Translatable ✓
⚙️ Configuration
Config File: config/translatable-builder.php
return [ // Enable/disable builder 'enabled' => env('TRANSLATABLE_BUILDER_ENABLED', true), // Route configuration 'route_prefix' => 'translatable-builder', 'middleware' => ['web'], // File paths 'migration_path' => 'database/migrations', 'model_path' => 'app/Models', 'seeder_path' => 'database/seeders', 'model_namespace' => 'App\\Models', // Available column types 'column_types' => [ 'string', 'text', 'integer', 'bigInteger', 'decimal', 'float', 'boolean', 'date', 'dateTime', 'time', 'json', 'jsonb', 'uuid', 'enum', 'foreignId', 'morphs', ], // Available index types 'index_types' => [ 'index' => 'Index', 'unique' => 'Unique', 'primary' => 'Primary Key', ], ];
🔑 Key Concepts
Translatable Columns
When you mark a column as "Translatable":
- It's removed from the main table
- It's added to the translations table
- The builder automatically handles:
- Translation table creation
- Locale column (indexed)
- Foreign key to main table
- Unique constraint on
[foreign_key, locale]
Example Structure
Before (without Translations):
$table->string('name'); $table->text('description');
After (with Translations):
Main Table (products):
- id
- sku
- price
- stock
- created_at
- updated_at
Translations Table (products_translations):
- id
- products_id (foreign key)
- locale (indexed)
- name
- description
- unique(products_id, locale)
📁 Package Structure
translatable-migration-builder/
├── config/
│ └── translatable-builder.php # Configuration
├── resources/
│ ├── views/
│ │ ├── index.blade.php # Main view
│ │ └── livewire/
│ │ └── builder.blade.php # Livewire component
│ ├── css/
│ │ └── builder.css # Styling (optional)
│ ├── js/
│ │ └── builder.js # JavaScript (optional)
│ └── examples/
│ ├── 2024_03_22_120000_create_products_table.php
│ └── Product.php
├── routes/
│ └── web.php # Routes
├── src/
│ ├── Builders/
│ │ ├── Column.php # Column model
│ │ └── Table.php # Table model
│ ├── Commands/
│ │ └── LaunchBuilderCommand.php # Artisan command
│ ├── Generators/
│ │ ├── MigrationGenerator.php # Migration code generator
│ │ └── ModelGenerator.php # Model code generator
│ ├── Http/
│ │ └── Controllers/
│ │ └── BuilderController.php # Route controller
│ ├── Livewire/
│ │ └── BuilderComponent.php # Livewire component
│ ├── Support/ # Helper utilities (optional)
│ ├── Contracts/ # Interfaces (optional)
│ └── TranslatableMigrationBuilderServiceProvider.php
├── composer.json
└── README.md
🛠️ Architecture
Builder Classes
Column.php - Represents a single database column
$column = new Column('title', 'string'); $column->setLength(200) ->setNullable(false) ->setTranslatable(true);
Table.php - Represents a complete table structure
$table = new Table('products'); $table->setPrimaryKey('id') ->setTimestamps(true) ->addColumn($column);
Generators
MigrationGenerator.php - Generates Laravel migration PHP code
$generator = new MigrationGenerator(); $code = $generator->generate($table); $filename = $generator->getFilename($table);
ModelGenerator.php - Generates Laravel model with Translatable trait
$generator = new ModelGenerator(); $code = $generator->generate($table);
Livewire Component
BuilderComponent.php - Manages UI state and interactions
addColumn()- Add new columnremoveColumn()- Remove columnupdateColumn()- Update column propertiesgoToStep()- Navigate between stepsgeneratePreview()- Generate preview codedownloadMigration()- Export migration filedownloadModel()- Export model filegenerateInProject()- Generate migration, models, repository files, and seeder directly in Laravel project
🎯 Best Practices
Table Naming
// Use plural form for tables products, users, posts, categories // Translation tables auto-generated as products_translations, users_translations, etc.
Column Naming
// Use snake_case user_id, category_id, product_name // Foreign keys follow convention {singular_table}_id (user_id, category_id)
Translatable Fields
// Good - Textual content title, description, content, slug, meta_title, meta_description // Bad - Config/status fields (should NOT be translatable) is_active, status, price, stock
🔒 Security
Access Control
By default, the builder is accessible to all authenticated users. Restrict access by modifying middleware:
// config/translatable-builder.php 'middleware' => ['web', 'auth', 'admin'], // Add custom middleware
Environment Control
// .env TRANSLATABLE_BUILDER_ENABLED=true # Set to false in production
🐛 Troubleshooting
Builder not loading?
- Ensure Livewire is properly installed
- Check if route is accessible:
php artisan route:list | grep translatable - Verify
TRANSLATABLE_BUILDER_ENABLEDistruein .env
Generated migration fails?
- Check table name doesn't conflict with existing tables
- Verify foreign key references exist
- Ensure column names are valid MySQL identifiers
Model not working with Translatable?
- Verify
$translatedAttributesare set correctly - Check foreign key names match migration
- Ensure Astrotomic package is installed
📚 Additional Resources
📝 License
MIT License - See LICENSE file
🤝 Contributing
Contributions are welcome! Please submit issues and pull requests.
📧 Support
For issues, questions, or feature requests, please open an issue on GitHub.
Built with ❤️ for Laravel developers who value clean, translatable databases


