Installation Add the package via Composer:
composer require bordeux/language-bundle
Register the bundle in config/app.php under providers:
Bordeaux\LanguageBundle\BordeauxLanguageBundle::class,
And import the routing in config/app.php under routes:
Bordeaux\LanguageBundle\Routing\LanguageRouting::class,
Database Setup
Run migrations to create the required tables (check src/Resources/migrations/ for schema):
php artisan migrate
The bundle expects tables for:
language (stores language codes, names, etc.)translation (stores key-value pairs per language)currency (if using currency features)First Use Case: Basic Translation Load translations dynamically in a controller:
use Bordeaux\LanguageBundle\Manager\TranslationManager;
class MyController extends Controller
{
public function show()
{
$translationManager = $this->container->get('bordeux.language.manager.translation');
$translation = $translationManager->getTranslation('my_key', 'en'); // 'en' = language code
return view('page', ['message' => $translation]);
}
}
SonataAdmin Integration
Enable the bundle’s SonataAdmin provider in config/packages/sonata_admin.php:
providers:
- Bordeaux\LanguageBundle\Sonata\LanguageAdmin
Clear cache:
php artisan cache:clear
Storing Translations
Use the TranslationManager to save translations dynamically:
$translationManager = $this->container->get('bordeux.language.manager.translation');
$translationManager->saveTranslation('my_key', 'Hello, {name}!', 'en');
Fetching Translations Retrieve translations with fallback to default language:
$translation = $translationManager->getTranslation('my_key', 'fr', 'en'); // Fallback to 'en' if 'fr' missing
Dynamic Placeholders Replace placeholders in translations:
$message = $translationManager->getTranslation('greeting', 'en');
$rendered = str_replace('{name}', 'John', $message); // Manual replacement (no built-in interpolation)
Language Switching Override the current language in a request:
$request->setLocale('es'); // Manually set language
Storing Currency Values Save currency rates dynamically:
$currencyManager = $this->container->get('bordeux.language.manager.currency');
$currencyManager->saveRate('USD', 'EUR', 0.85);
Fetching Converted Values Convert amounts between currencies:
$convertedAmount = $currencyManager->convert(100, 'USD', 'EUR'); // Returns 85.00
Admin Panel Configuration
Extend the LanguageAdmin class to customize fields:
use Bordeaux\LanguageBundle\Sonata\LanguageAdmin as BaseLanguageAdmin;
class CustomLanguageAdmin extends BaseLanguageAdmin
{
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper->add('name', 'text', ['label' => 'Language Name']);
// Custom fields here
}
}
Translation CRUD Use the SonataAdmin panel to:
Routing
Access the admin panel at /admin/language (configurable in routing.yml).
Fallback to Laravel’s lang Files
Combine with Laravel’s built-in translations for hybrid workflows:
$translation = $translationManager->getTranslation('key') ?: __('fallback.key');
Publish Translations Publish the bundle’s translations (if any) to extend them:
php artisan vendor:publish --provider="Bordeux\LanguageBundle\BordeauxLanguageBundle" --tag=translations
Deprecated/Archived Package
No Built-in Interpolation
{name}) require manual str_replace or regex. Consider extending the TranslationManager:
$translationManager->setInterpolator(function ($translation, $params) {
return strtr($translation, $params);
});
SonataAdmin Version Mismatch
SonataAdmin integration.Database Schema Assumptions
language, translation, currency) must exist. If migrations fail, manually create them or adjust the bundle’s schema.No Cache Busting
Cache::remember("translation_{$key}_{$locale}", 3600, function() use ($key, $locale) {
return $translationManager->getTranslation($key, $locale);
});
Check Database Records Verify translations/currencies exist in the DB:
SELECT * FROM translation WHERE key = 'my_key';
Enable Debugging
Add logging to the TranslationManager:
$translationManager->setLogger($this->container->get('logger'));
Override Services
Replace the TranslationManager with a debug version:
# config/services.yaml
Bordeaux\LanguageBundle\Manager\TranslationManager:
arguments:
- '@database_connection'
- '@logger' # Inject logger for debugging
Custom Translation Sources
Extend TranslationManager to support additional sources (e.g., API, files):
class ApiTranslationManager extends TranslationManager
{
public function getTranslation($key, $locale = null)
{
$apiTranslation = $this->fetchFromApi($key, $locale);
return $apiTranslation ?: parent::getTranslation($key, $locale);
}
}
Event Listeners Listen for translation events (if the bundle emits them):
use Bordeaux\LanguageBundle\Event\TranslationEvent;
Event::listen(TranslationEvent::class, function (TranslationEvent $event) {
// Log or modify translations before saving
});
Custom Validation Add validation to translations (e.g., length, format):
$translationManager->setValidator(function ($translation) {
return strlen($translation) < 200; // Example: enforce max length
});
N+1 Query Problem Fetching translations in loops triggers multiple queries. Use eager loading:
$translations = $translationManager->getTranslations(['key1', 'key2'], 'en');
Locale Detection
The bundle may not auto-detect locale. Override the LocaleListener:
$request->setLocale($this->detectLocale()); // Custom logic
Backward Compatibility If upgrading from an older version, check for:
getTranslation() parameters).bordeux.language.manager vs. bordeux.language.manager.translation).Data Migration Export/import translations if schema changes:
php artisan db:seed --class=LanguageSeeder
How can I help you explore Laravel packages today?