syriable/localizator
最新稳定版本:v1.4.0
Composer 安装命令:
composer require syriable/localizator
包简介
AI-powered Laravel package for automatic translation scanning and generation
README 文档
README
An advanced Laravel package for automatic translation scanning and AI-powered translation generation. Built for Laravel 12+ with modern PHP standards and FilamentPHP 4 compatibility.
🚀 Features
- 🔍 Comprehensive Scanning: Automatically scan PHP, Blade, Vue.js, and JavaScript files for translation functions
- 🚫 Smart Comment Detection: Automatically skip translation keys in comments (
/* {{ __('key') }} */) - 🧹 Remove Missing Keys: Clean up unused translation keys from language files with
--remove-missing - 🤖 AI-Powered Translations: Generate translations using OpenAI, Claude, Google Translate, or Azure Translator
- 📁 Multiple Formats: Support for both JSON and PHP array translation files
- ⚙️ Highly Configurable: Extensive configuration options for customizing behavior
- 🧪 Production Ready: Built with PSR standards, PHPStan level 8, and comprehensive testing
- 🔧 Developer Friendly: Interactive CLI commands with progress indicators and validation
- 💾 Safe Operations: Automatic backups and dry-run capabilities
📋 Requirements
- PHP 8.3 or higher
- Laravel 12.0 or higher
- Composer
📦 Installation
Install the package via Composer:
composer require syriable/localizator
Publish the configuration file:
php artisan vendor:publish --tag="localizator-config"
This will publish the configuration file to config/localizator.php.
⚙️ Configuration
The package comes with extensive configuration options. Here are the key settings:
// config/localizator.php return [ // Translation file type: 'default' (PHP) or 'json' 'localize' => env('LOCALIZATOR_TYPE', 'default'), // Source language for AI translations 'source_language' => env('LOCALIZATOR_SOURCE_LANG', 'en'), // Use nested array structure for dot notation keys 'nested' => true, // Directories to scan for translation functions 'dirs' => [ app_path(), resource_path('views'), resource_path('js'), resource_path('vue'), base_path('routes'), ], // File patterns to include 'patterns' => [ '*.php', '*.blade.php', '*.vue', '*.js', '*.ts', ], // Translation functions to look for 'functions' => [ '__', 'trans', 'trans_choice', '@lang', '@choice', 'Lang::get', 'Lang::choice', '$t', // Vue i18n '$tc', // Vue i18n choice ], // AI translation settings 'ai' => [ 'provider' => env('LOCALIZATOR_AI_PROVIDER', 'openai'), 'openai' => [ 'api_key' => env('OPENAI_API_KEY'), 'model' => env('OPENAI_MODEL', 'gpt-3.5-turbo'), ], 'claude' => [ 'api_key' => env('ANTHROPIC_API_KEY'), 'model' => env('CLAUDE_MODEL', 'claude-3-sonnet-20240229'), ], // ... more AI provider configurations ], ];
Environment Variables
Add these to your .env file:
# Basic Configuration LOCALIZATOR_TYPE=default LOCALIZATOR_SOURCE_LANG=en # AI Provider (choose one) LOCALIZATOR_AI_PROVIDER=openai # OpenAI Configuration OPENAI_API_KEY=your-openai-api-key OPENAI_MODEL=gpt-3.5-turbo # Or Claude Configuration ANTHROPIC_API_KEY=your-anthropic-api-key CLAUDE_MODEL=claude-3-sonnet-20240229 # Or Google Translate Configuration GOOGLE_TRANSLATE_API_KEY=your-google-api-key GOOGLE_CLOUD_PROJECT_ID=your-project-id # Or Azure Translator Configuration AZURE_TRANSLATOR_KEY=your-azure-key AZURE_TRANSLATOR_REGION=your-region AZURE_TRANSLATOR_ENDPOINT=your-endpoint
🛠️ Usage
Automatic Generation (Recommended)
Generate all translation files automatically without any interactive prompts:
# Generate for default locales (configured in config/localizator.php) php artisan localizator:generate # Generate for specific locales php artisan localizator:generate en es fr de # Silent mode (no output except errors) php artisan localizator:generate --silent # With AI auto-translation php artisan localizator:generate es fr --auto-translate # Generate JSON files instead of PHP php artisan localizator:generate en --format=json # Force overwrite without backup php artisan localizator:generate en --force
Interactive Scanning
Scan your application with interactive prompts and review options:
php artisan localizator:scan en es fr de
Advanced Options
The scan command supports various options for different use cases:
# Dry run - see what would be done without making changes php artisan localizator:scan en --dry-run # Remove missing translation keys (clean up unused keys) php artisan localizator:scan en --remove-missing # Sort translation keys alphabetically php artisan localizator:scan en --sort # Enable AI-powered auto-translation php artisan localizator:scan es fr --auto-translate # Auto-translate with review process php artisan localizator:scan es --auto-translate --review # Specify AI provider and source language php artisan localizator:scan es --auto-translate --provider=claude --source-lang=en # Custom batch size for AI translations php artisan localizator:scan es --auto-translate --batch-size=25 # Generate JSON files instead of PHP php artisan localizator:scan en --format=json # Create backups of existing files php artisan localizator:scan en --backup # Verbose output for debugging php artisan localizator:scan en -v
Command Comparison
| Feature | localizator:generate |
localizator:scan |
|---|---|---|
| Interaction | Fully automatic, zero prompts | Interactive with prompts and choices |
| Locale Selection | Uses config defaults or arguments | Prompts for locale selection if not specified |
| AI Review | Auto-accepts all translations | Optional review process for AI translations |
| Best for | CI/CD, automated workflows | Manual control, reviewing translations |
| Speed | Fast, no waiting for input | Slower due to interactive prompts |
| Silent Mode | Yes (--silent flag) |
No |
| Configuration | Uses locales from config |
Always prompts if no arguments |
Recommendation: Use localizator:generate for most cases, especially in automated environments. Use localizator:scan when you need to review and approve translations manually.
Interactive Mode
When you run the command without specifying locales, it will prompt you to select from supported languages:
php artisan localizator:scan
🔍 What Gets Scanned
The package automatically detects and extracts translation keys from:
Comment Detection & Skipping
NEW in v1.4.0: The package now automatically skips translation keys found in comments, preventing disabled or temporary keys from being added to your language files.
Supported Comment Types:
// C-style comments /* {{ __('disabled.key') }} */ // Single-line comments // {{ __('commented.key') }} // Blade comments {{-- {{ __('blade.disabled.key') }} --}} // HTML comments <!-- {{ __('html.commented.key') }} --> // Multiline comments /* * {{ __('multiline.disabled.key1') }} * {{ __('multiline.disabled.key2') }} */
Why This Matters:
- ✅ Prevents cluttering language files with temporary/disabled keys
- ✅ Keeps your translations clean and organized
- ✅ Allows developers to comment out translations without affecting builds
- ✅ Works automatically - no configuration needed
File Types Scanned
PHP Files
__('auth.login.title') // → resources/lang/en/auth.php: ['login' => ['title' => '...']] trans('validation.email.required') // → resources/lang/en/validation.php: ['email' => ['required' => '...']] trans_choice('messages.items', $count) Lang::get('dashboard.widgets.summary') Lang::choice('items.count', 5)
Blade Templates
@lang('app.title') @choice('messages.items', $itemCount) {{ __('buttons.submit') }} {{ trans('labels.name') }}
Vue.js Components
<template> <h1>{{ $t('dashboard.title') }}</h1> <p>{{ $tc('users.count', userCount) }}</p> </template> <script> this.$t('notifications.success') this.$tc('items.found', itemsFound) </script>
JavaScript Files
$t('messages.welcome') $tc('items.selected', selectedCount)
🏗️ Intelligent Nested Structure
The package automatically organizes translation files based on dot notation keys, following Laravel's best practices:
How It Works
Translation Key → Generated File Structure
-
auth.login.title→resources/lang/en/auth.phpreturn [ 'login' => [ 'title' => 'Login Title' ] ];
-
validation.custom.email.required→resources/lang/en/validation.phpreturn [ 'custom' => [ 'email' => [ 'required' => 'Email is required' ] ] ];
Key Benefits
✅ Organized Structure: Files are automatically organized by context
✅ Laravel Standard: Follows Laravel's recommended translation file structure
✅ Deep Nesting: Supports unlimited nesting levels (auth.forms.login.validation.required)
✅ Backward Compatible: Can be disabled with 'nested' => false
✅ Merge Existing: Intelligently merges with existing translation files
🧹 Remove Missing Keys
NEW in v1.4.0: The --remove-missing option has been improved to properly clean up unused translation keys from your language files.
How It Works
When you delete translation keys from your source code, they remain in your language files. The --remove-missing flag solves this by:
- Scanning your codebase for currently used translation keys
- Comparing with existing translation files
- Removing keys that no longer exist in your source code
- Preserving all keys that are still in use
Usage Examples
# Remove unused keys from English translations php artisan localizator:scan en --remove-missing # Remove unused keys and create backups php artisan localizator:scan en --remove-missing --backup # See what would be removed without making changes php artisan localizator:scan en --remove-missing --dry-run # Remove unused keys from multiple locales php artisan localizator:scan en es fr --remove-missing
Before & After Example
Before (your source code changed):
// You removed this from your Blade file: // {{ __('auth.old_feature') }} // But kept this: {{ __('auth.login.title') }}
Translation file before cleanup:
// resources/lang/en/auth.php return [ 'login' => ['title' => 'Login'], 'old_feature' => 'This is no longer used', // ← Will be removed ];
After running --remove-missing:
// resources/lang/en/auth.php return [ 'login' => ['title' => 'Login'], // ← Preserved // 'old_feature' removed automatically ];
Safety Features
- ✅ Dry Run: Use
--dry-runto preview changes before applying - ✅ Backups: Use
--backupto create timestamped backups - ✅ Incremental: Only removes unused keys, preserves translations
- ✅ Multi-format: Works with both PHP and JSON translation files
🤖 AI Translation Features
Supported AI Providers
- OpenAI: GPT-3.5 Turbo, GPT-4, and other models
- Anthropic Claude: Claude 3 Sonnet, Haiku, and Opus models
- Google Translate: Google Cloud Translation API
- Azure Translator: Microsoft Azure Translator Text API
Translation Context
Provide context to improve AI translations:
// config/localizator.php 'ai' => [ 'context' => [ 'domain' => 'e-commerce', // Business domain 'tone' => 'friendly', // Communication tone 'additional_context' => 'This is a Laravel application for online shopping', ], ],
Batch Processing
AI translations are processed in batches to optimize API usage:
'ai' => [ 'batch_size' => 50, // Translations per batch 'rate_limit' => 60, // Requests per minute ],
Validation
Automatic validation ensures translation quality:
- Placeholder preservation (
:name,{count}, etc.) - Length validation
- Key naming convention checks
📁 Output Formats
JSON Format
{
"welcome.message": "Welcome to our application",
"auth.failed": "These credentials do not match our records",
"dashboard.title": "Dashboard"
}
PHP Array Format
Nested Structure (Default)
With 'nested' => true in configuration, translation keys use dot notation to create organized, nested file structures:
// For keys like 'auth.login.title', 'auth.login.button' // File: resources/lang/en/auth.php return [ 'login' => [ 'title' => 'Login', 'button' => 'Sign In', 'failed' => 'These credentials do not match our records.', ], 'register' => [ 'title' => 'Create Account', 'button' => 'Sign Up', ], 'logout' => 'Sign Out', // Single-level key ]; // For keys like 'validation.custom.email.required' // File: resources/lang/en/validation.php return [ 'custom' => [ 'email' => [ 'required' => 'Email is required', 'email' => 'Must be a valid email', ], 'password' => [ 'min' => 'Password must be at least 8 characters', ], ], 'attributes' => [ 'first_name' => 'First Name', 'last_name' => 'Last Name', ], ];
Flat Structure (Legacy)
With 'nested' => false, keys remain flat within files:
// File: resources/lang/en/auth.php return [ 'login.title' => 'Login', 'login.button' => 'Sign In', 'register.title' => 'Create Account', ];
🧪 Testing
Run the package tests:
composer test
Run static analysis:
composer analyse
Fix code style:
composer format
Run all quality checks:
composer test && composer analyse && composer format
📈 Performance
The package is optimized for large codebases:
- Efficient File Scanning: Uses Symfony Finder for fast directory traversal
- Regex Optimization: Compiled patterns for translation function detection
- Memory Management: Processes files in chunks to handle large projects
- Caching: Optional caching of scan results to speed up subsequent runs
🛡️ Security
- Validates all translation keys against configurable patterns
- Sanitizes file paths and prevents directory traversal
- Respects Laravel's security practices for file operations
- API keys are stored securely in environment variables
🔧 Advanced Configuration
Custom Translation Functions
Add your own translation function patterns:
'functions' => [ '__', 'trans', 'myCustomTransFunction', // Your custom function 'MyClass::translate', // Static method ],
File Exclusion
Exclude specific files or directories:
'exclude' => [ 'vendor', 'node_modules', 'storage', 'specific-file.php', 'temp-directory', ],
Custom Output Settings
Customize the generated files:
'output' => [ 'indent' => 2, // Spaces for indentation 'line_length' => 80, // Maximum line length 'comments' => true, // Include generation comments 'backup' => true, // Create backups ],
🚨 Troubleshooting
Common Issues
1. No translation keys found
- Check that your
functionsconfiguration includes all translation methods used in your codebase - Verify that the
dirsandpatternssettings cover your file locations - Ensure keys aren't all commented out (v1.4.0+ automatically skips commented keys)
- Use
--dry-run -vto see detailed scanning information
2. AI translation failures
- Verify your API keys are correctly set in
.env - Check your API quotas and rate limits
- Use smaller batch sizes if encountering timeout errors
3. --remove-missing not working
- Ensure the command completed successfully (exit code 0)
- Check that translation keys were actually removed from your source code
- Use
--dry-runto see what keys would be removed before running - Verify you're scanning the correct directories with
--dry-run -v
4. Permission errors
- Ensure Laravel has write permissions to the
resources/langdirectory - Check file ownership and permissions
Debug Mode
Enable verbose output for debugging:
php artisan localizator:scan en -v
Log Analysis
Check Laravel logs for detailed error information:
tail -f storage/logs/laravel.log
🤝 Contributing
We welcome contributions! Please see CONTRIBUTING.md for guidelines.
Development Setup
- Clone the repository
- Install dependencies:
composer install - Run tests:
composer test - Run static analysis:
composer analyse - Fix code style:
composer format
📄 Changelog
Please see CHANGELOG.md for more information on what has changed recently.
🔒 Security
If you discover any security-related issues, please email security@syriable.com instead of using the issue tracker.
📝 License
The MIT License (MIT). Please see License File for more information.
🙏 Credits
- Syriable Team
- All Contributors
- Inspired by amiranagram/localizator
🔗 Related Packages
💡 Tips & Best Practices
1. Organize Translation Keys
Use dot notation for hierarchical organization:
__('dashboard.widgets.sales.title') __('forms.validation.required') __('emails.welcome.subject')
2. Use Placeholders
Keep translations flexible with placeholders:
__('welcome.greeting', ['name' => $user->name]) __('items.count', ['count' => $itemCount])
3. Review AI Translations
Always review AI-generated translations for:
- Cultural appropriateness
- Context accuracy
- Technical terminology
- Brand consistency
4. Version Control
Include translation files in version control but consider:
- Using separate branches for translation updates
- Implementing review processes for translation changes
- Automated testing for translation completeness
5. Performance Optimization
For large applications:
- Use JSON format for better performance
- Enable caching in production
- Consider splitting translations into smaller, feature-specific files
Made with ❤️ by Syriable
统计信息
- 总下载量: 10
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 0
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-08-29