edulazaro/laratext
Laratext manages and auto-translates Laravel text strings by using both key and text for readable, stable translations. Includes @text directive and text() helper, scans/updates language files, and supports OpenAI, Google Translate, and more.
Installation:
composer require edulazaro/laratext
php artisan vendor:publish --tag="texts"
Configure .env with API keys (e.g., OPENAI_API_KEY) and config/texts.php with supported languages.
First Use Case: Replace a hardcoded string in Blade:
<!-- Before -->
<h1>Welcome, {{ $user->name }}!</h1>
<!-- After -->
@text('welcome.user', 'Welcome, :name!', ['name' => $user->name])
Auto-Generate Translations: Run the scan command to auto-translate missing keys:
php artisan laratext:scan --write
@lang or hardcoded strings with @text().text('key', 'default_value') in controllers/services.config/texts.php for translator settings and supported languages.laratext:scan options for managing translations.auth.login.title).@text('user.profile.edit') <!-- Auto-generates "Profile Edit" -->
:placeholder syntax for dynamic content:
text('cart.summary', 'Total: $:amount', ['amount' => $total]);
@text over @lang for consistency:
@text('errors.validation.required', 'The :field is required.', ['field' => 'email'])
@text('settings.not_found', 'Settings not found', 'Fallback text')
$message = text('notifications.email.subject', 'Your order #:order_id', ['order_id' => 12345]);
$validator->errorBag('default')->messages()->put('email', text('errors.invalid_email'));
# After adding new keys
php artisan laratext:scan --write
# Before production
php artisan laratext:scan --write --prune
# Translate only Spanish
php artisan laratext:scan --write --lang=es
# Use Claude for high-quality translations
php artisan laratext:scan --write --translator=claude
app()->setLocale('es'); // Switch to Spanish
app/Providers/AppServiceProvider:
LaravelLocalization::addLangs(['en', 'es', 'fr'], 'flags');
LaravelLocalization::setFallbackLocales(['en', 'es']);
eduLazaro\Laratext\Middleware\SetLocale to set locale from URL or session.return response()->json(['message' => text('api.success')]);
$this->app->bind(TranslatorInterface::class, function () {
return new class implements TranslatorInterface {
public function translate(string $text, string $from, array $to): array {
return array_fill_keys($to, $text); // Mock: return same text
}
};
});
Key Drift:
--resync to force a full retranslation or manually update lang/{locale}.json.--only-missing to skip).Placeholder Mismatches:
:name) must match exactly across languages. Typos in one language break replacements./:\w+/.API Rate Limits:
--dry to preview changes before writing.retries in config).translateMany().Orphaned Keys:
@text calls leave stale keys in JSON files.--prune periodically:
php artisan laratext:scan --write --prune
Auto-Generated Text:
user_profile_edit → "User Profile Edit") may not match intent.--resync to override auto-generated values.--diff to see changes before applying:
php artisan laratext:scan --diff
config/texts.php:
'debug' => env('APP_DEBUG', false),
storage/logs/laravel.log for API failures (e.g., invalid API keys, timeouts).Default Locale:
APP_LOCALE in .env matches the default locale in lang/{locale}.json.APP_LOCALE=es, translations must exist in lang/es.json.Language Codes:
en, es) for consistency with Laravel’s localization.en-US) unless explicitly supported by your translator.Translator Priorities:
default_translator in config/texts.php applies globally. Override per-command with --translator.google for high-volume, low-cost translations:
php artisan laratext:scan --write --translator=google
Custom Translators:
translateMany() to reduce API calls:
public function translateMany(array $texts, string $from, array $to): array {
// Use bulk API endpoints (e.g., Google Translate batch)
}
Illuminate\Support\Facades\Cache:
$cacheKey = "laratext:{$text}:{$from}:".implode(',', $to);
return Cache::remember($cacheKey, now()->addHours(1), function () use ($text, $from, $to) {
return $this->translate($text, $from, $to);
});
Key Sanitization:
generateTextFromKey() method in a custom translator.Pre-Translation Hooks:
events to validate keys before translation:
// In EventServiceProvider
public function boot() {
Event::listen('laratext.scanning', function ($keys) {
// Validate keys against a regex or business rules
});
}
Post-Translation Hooks:
// In a service provider
Event::listen('laratext.translated', function ($key, $translations) {
foreach ($translations as $locale => &$text) {
$text = str_replace('AI', 'Our Team', $text); // Branding fix
}
});
translateMany() over individual calls for large scans.--exclude to skip non-critical files (e.g., tests):
php artisan laratext:scan --write --exclude="tests/"
php artisan laratext:scan --write --
How can I help you explore Laravel packages today?