om/potrans
Laravel package for managing translations with import/export tools and a simple UI/API. Helps keep language files in sync, edit keys/values, detect missing strings, and streamline localization workflows across your app.
## Getting Started
1. **Installation**
Add to your Laravel project via Composer (preferably in `require-dev`):
```bash
composer require --dev om/potrans
Or globally for CLI access:
composer global require om/potrans
First Command Verify installation with:
./vendor/bin/potrans --help
Key commands:
potrans google (Google Translate API)potrans deepl (DeepL API)Initial Translation
Translate a .po file to Spanish using Google Translate:
./vendor/bin/potrans google ./resources/lang/en/messages.po ./resources/lang/es --lang=es --apikey=$GOOGLE_TRANSLATE_API_KEY
Note: Laravel’s .env won’t auto-load; pass keys via CLI or set them in the current directory’s .env.
xgettext -o ./resources/lang/messages.pot --from-code=UTF-8 ./app --keyword=_ --keyword=__ --keyword=trans_choice
potrans in composer.json scripts:
"scripts": {
"translate:es": "potrans google ./resources/lang/messages.pot ./resources/lang/es --lang=es --apikey=$GOOGLE_TRANSLATE_API_KEY --ignore='^#, fuzzy$'",
"translate:all": "potrans google ./resources/lang/messages.pot ./resources/lang --lang=de,fr,es --apikey=$GOOGLE_TRANSLATE_API_KEY"
}
Run with:
composer translate:es
Use in GitHub Actions to auto-update translations on main branch:
- name: Translate new strings
run: |
composer translate:all
git add ./resources/lang/
git diff --quiet || git commit -m "chore: update translations"
git push
./vendor/bin/potrans deepl ./resources/lang/en/*.po ./resources/lang/de --lang=de --apikey=$DEEPL_API_KEY --format=po
--ignore="^#, fuzzy$|^#, translator-comments$"
Create a custom translator (e.g., app/Translators/CustomTranslator.php):
<?php
namespace App\Translators;
use Potrans\Translator\TranslatorInterface;
class CustomTranslator implements TranslatorInterface {
public function translate(string $text, string $sourceLang, string $targetLang): string {
// Add custom logic (e.g., fallback to Google if DeepL fails)
return str_replace('foo', 'bar', $text); // Example
}
}
Use it via CLI:
./vendor/bin/potrans deepl ./locale/messages.po ./locale --translator=app/Translators/CustomTranslator --lang=fr
Sync potrans cache with Laravel’s cache:
// In a service provider
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\File;
Cache::remember('potrans_cache', 3600, function () {
$cacheDir = base_path('.potrans/cache');
return File::exists($cacheDir) ? File::get($cacheDir) : null;
});
.env Limitation: potrans ignores Laravel’s .env. Create a .env in your project root or pass keys via CLI:
--apikey=$(cat .env | grep GOOGLE_TRANSLATE_API_KEY | cut -d'=' -f2)
--debug to avoid hitting caps.zh-CN; DeepL uses ZH. potrans auto-converts, but verify with:
./vendor/bin/potrans deepl --debug ./locale/messages.po ./locale --lang=zh-CN
EN for unsupported languages. Use --ignore to skip or handle in a custom translator.~/.potrans/cache/. In Docker/Laravel Forge, this may fail. Override with:
--cache-dir=./storage/potrans_cache
--force to bypass cache for updated strings. Avoid --all (deprecated in v1.0+).potrans regenerates .mo files. To avoid:
--only # Generate only .po files
.po files are UTF-8. Use:
iconv -f ISO-8859-1 -t UTF-8 input.po -o output.po
--debug to see raw responses:
./vendor/bin/potrans deepl --debug ./locale/messages.po ./locale --lang=fr
Common errors:
curl -X POST "https://api-free.deepl.com/v2/translate" -H "Authorization: DeepL-Auth-Key $DEEPL_API_KEY".potrans uses symfony/finder. If Laravel’s Illuminate/Filesystem interferes, alias the namespace in composer.json:
"autoload": {
"psr-4": {
"Symfony\\Component\\Finder\\": "vendor/symfony/finder/"
}
}
potrans in an Artisan command for Laravel-native usage:
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Symfony\Component\Process\Process;
use Symfony\Component\Process\Exception\ProcessFailedException;
class TranslateCommand extends Command {
protected $signature = 'translate:lang {lang}';
protected $description = 'Translate Laravel lang files';
public function handle() {
$process = new Process(['vendor/bin/potrans', 'google', './resources/lang/en/messages.pot', './resources/lang', '--lang=' . $this->argument('lang'), '--apikey=' . env('GOOGLE_TRANSLATE_API_KEY')]);
$process->run();
if (!$process->isSuccessful()) {
throw new ProcessFailedException($process);
}
}
}
Run with:
php artisan translate:lang es
.po files by domain:
./vendor/bin/potrans google ./resources/lang/en/auth.po ./resources/lang/es --lang=es
./vendor/bin/potrans google ./resources/lang/en/validation.po ./resources/lang/es --lang=es
parallel -j 4 ./vendor/bin/potrans google ./resources/lang/en/{}.po ./resources/lang/es --lang=es ::: auth validation errors
Potrans\Command\TranslatorCommand to add logic before/after translation.Potrans\Formatter\PoFormatter to support Laravel-specific PO file structures (e.g., custom headers).
---
How can I help you explore Laravel packages today?