Installation
Add the bundle to your composer.json:
composer require cvele/translation-bundle
Register the bundle in config/bundles.php (Symfony) or config/app.php (Laravel via Symfony bridge):
return [
// ...
SchmittJoh\JMSTranslationBundle\JMSTranslationBundle::class => ['all' => true],
];
Configuration Publish the default config:
php artisan vendor:publish --tag=jms-translation-config
Update config/packages/jms_translation.yaml (or config/jms_translation.php if using Laravel's YAML-to-PHP adapter).
First Use Case Translate a message in a controller or Blade template:
// Symfony
$this->get('translator')->trans('message.key', ['%name%' => 'John']);
// Laravel (via Symfony bridge)
$translator = app('translator');
echo $translator->trans('message.key', ['%name%' => 'John']);
Translation Domains
Use domains to isolate translations (e.g., admin, frontend):
# config/packages/jms_translation.yaml
jms_translation:
configs:
admin:
dirs: ['%kernel.project_dir%/translations/admin']
output_dir: '%kernel.project_dir%/var/cache/admin'
Access via:
$translator->transChoice('admin.message', 1, ['%count%' => 1], 'admin');
Pluralization & Choice Handling
Leverage Symfony’s transChoice for dynamic pluralization:
$translator->transChoice('messages.new', $count, ['%count%' => $count]);
Define translations in messages.en.yaml:
messages:
new:
0: "No new messages"
1: "One new message"
%d: "%count% new messages"
Translation Extraction Automate extraction from PHP/Blade:
php artisan jms:translation:extract
Configure extraction paths in config/packages/jms_translation.yaml:
jms_translation:
extractors:
php:
dirs: ['src']
twig:
dirs: ['templates']
Caching & Performance Enable caching for compiled translations:
jms_translation:
file_cache_dir: '%kernel.cache_dir%/translations'
Clear cache after updates:
php artisan cache:clear
Laravel-Specific Integration Bind the translator to Laravel’s service container (if not using Symfony bridge):
// config/app.php
'providers' => [
// ...
SchmittJoh\JMSTranslationBundle\JMSTranslationBundle::class,
],
Use in Blade:
{{ trans('message.key', ['%var%' => $value]) }}
Namespace Conflicts
Ensure translation keys are namespaced (e.g., admin.user.profile) to avoid collisions. Use domains for logical grouping.
Extractor Configuration
Misconfigured extractors may miss translations. Verify dirs paths in jms_translation.yaml and test extraction:
php artisan jms:translation:extract --dry-run
Caching Quirks
php artisan cache:clear
php artisan jms:translation:compile
Laravel-Symfony Bridge Issues
translator service is properly bound:
$this->app->singleton('translator', function ($app) {
return new \Symfony\Component\Translation\Translator(
$app['config']['app.locale'],
new \SchmittJoh\JMSTranslationBundle\Translation\Loader\YamlFileLoader(
$app['kernel']->getProjectDir() . '/translations'
)
);
});
trans() helper for simplicity unless advanced features are needed.Pluralization Rules
config/packages/jms_translation.yaml:
jms_translation:
pluralization:
rules:
en: "n % 10 == 1 && n % 100 != 11 ? 1 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 2 : 0"
Translation Not Found
dirs.translator->getCatalogue()->all() to inspect loaded translations.Extractor Skipping Files
.php, .twig).Performance Bottlenecks
Xdebug or Blackfire.jms_translation.yaml to reduce memory usage.Custom Extractors
Create a custom extractor by implementing SchmittJoh\JMSTranslationBundle\Extractor\ExtractorInterface:
class CustomExtractor implements ExtractorInterface {
public function extract($file, $locale, LoaderInterface $loader) {
// Custom logic to parse files (e.g., JSON, XML)
return ['key' => 'value'];
}
}
Register in config:
jms_translation:
extractors:
custom:
class: App\Extractor\CustomExtractor
dirs: ['custom/path']
Dynamic Translation Loading Load translations dynamically at runtime:
$loader = $translator->getLoader();
$loader->load('dynamic', 'en', new \ArrayLoader(['key' => 'Dynamic Value']));
Middleware for Locale Switching Use middleware to set the locale based on headers/URL:
public function handle($request, Closure $next) {
$locale = $request->get('locale', config('app.locale'));
app('translator')->setLocale($locale);
return $next($request);
}
How can I help you explore Laravel packages today?