alexandre-fernandez/json-translation-bundle
Installation Add the package via Composer:
composer require alexandre-fernandez/json-translation-bundle
Enable the bundle in config/bundles.php:
AlexandreFernandez\JsonTranslationBundle\AlexandreFernandezJsonTranslationBundle::class => ['all' => true],
Configuration Publish the default config:
php bin/console config:dump-reference AlexandreFernandezJsonTranslationBundle
Update config/packages/alexandre_fernandez_json_translation.yaml:
alexandre_fernandez_json_translation:
locales: ['en', 'fr', 'es'] # Your supported locales
default_locale: 'en' # Fallback locale
storage: '%kernel.project_dir%/var/translations' # JSON storage path
First Use Case: Translating JSON Data
Store translations in JSON files (e.g., var/translations/messages.en.json):
{
"welcome": "Welcome, {name}!",
"error": {
"not_found": "Resource not found"
}
}
Use in a controller/service:
use AlexandreFernandez\JsonTranslationBundle\Translator\JsonTranslator;
class MyController extends AbstractController {
public function showWelcome(JsonTranslator $translator) {
$translation = $translator->trans('messages.welcome', ['%name%' => 'John']);
return new Response($translation); // Outputs: "Welcome, John!"
}
}
JsonTranslator to load translations on-demand:
$translator->load('custom', 'path/to/custom.json');
$translator->trans('custom.key');
config:
alexandre_fernandez_json_translation:
fallback_locales: ['en', 'fr']
var/translations/
├── messages.en.json
├── validation.fr.json
└── errors.es.json
$translator->trans('validation.email.required');
Bind the translator to Laravel’s container in AppServiceProvider:
public function register() {
$this->app->singleton(JsonTranslator::class, function ($app) {
return new JsonTranslator(
$app['kernel']->getProjectDir() . '/var/translations',
['en', 'fr'],
'en'
);
});
}
Create a custom Blade directive for translations:
Blade::directive('jsontrans', function ($expression) {
return "<?php echo app('AlexandreFernandez\\JsonTranslationBundle\\Translator\\JsonTranslator')->trans({$expression}); ?>";
});
Usage in Blade:
<h1>{{ jsontrans('messages.welcome', ['%name%' => $user->name]) }}</h1>
Override Symfony’s validator translations:
# config/validator/translation_mappings.yaml
AlexandreFernandezJsonTranslationBundle:
resource: "@AlexandreFernandezJsonTranslationBundle/Resources/translations/validator"
type: "json"
prefix: "validator"
Store custom validation rules in var/translations/validation.{locale}.json:
{
"constraints": {
"UniqueEntity": "This value is already used."
}
}
Generate JSON files from existing translations (e.g., Symfony’s translations directory):
php bin/console alexandre-fernandez:json-translation:dump
Outputs JSON files in var/translations/.
Check for syntax errors in translation files:
php bin/console alexandre-fernandez:json-translation:validate
Caching Issues
php bin/console cache:clear
config:
alexandre_fernandez_json_translation:
cache: false
Locale-Specific Paths
messages.en.json and messages.fr.json). Missing files will trigger fallback or errors.Variable Interpolation
%placeholder% syntax (not {placeholder}) for variable replacement:
{ "greeting": "Hello, %name%!" } // Correct
{ "greeting": "Hello, {name}!" } // Fails silently
File Permissions
var/translations/ is writable by the web server:
chmod -R 775 var/translations/
Check Loaded Translations Dump the translator’s loaded files:
$translator->getLoadedFiles(); // Returns array of loaded JSON paths
Enable Debug Mode
Log missing translations to var/log/dev.log:
alexandre_fernandez_json_translation:
debug: true
Validate JSON Manually
Use jsonlint.com to verify syntax in translation files.
Custom Storage
Extend AlexandreFernandez\JsonTranslationBundle\Storage\JsonStorage to support remote storage (e.g., S3):
class S3JsonStorage extends JsonStorage {
public function read($locale, $namespace) {
// Implement S3 logic
}
}
Translation Providers Add dynamic providers (e.g., database-backed translations):
$translator->addProvider(new DatabaseTranslationProvider());
Event Listeners
Listen for translation events (e.g., TranslationNotFoundEvent):
$eventDispatcher->addListener(
TranslationNotFoundEvent::class,
function (TranslationNotFoundEvent $event) {
// Fallback logic or logging
}
);
Preload Translations Load frequently used translations in a service constructor:
public function __construct(JsonTranslator $translator) {
$translator->load('messages', 'path/to/messages');
$translator->load('validation', 'path/to/validation');
}
Combine JSON Files Merge small JSON files into larger ones to reduce I/O operations:
// Before (multiple files)
messages.en.json, validation.en.json
// After (combined)
translations.en.json
How can I help you explore Laravel packages today?