awaresoft/sonata-translation-bundle
Installation via Composer (if not symlinked):
composer require awaresoft/sonata-translation-bundle
Note: Follow the README’s symlink instructions if modifying locally.
Enable the Bundle in config/bundles.php:
return [
// ...
Awaresoft\SonataTranslationBundle\SonataTranslationBundle::class => ['all' => true],
];
Basic Configuration in config/packages/sonata_translation.yaml:
sonata_translation:
default_locale: en
locales: [en, fr, es]
driver: doctrine # or 'orm'/'mongodb'
First Use Case:
use Awaresoft\SonataTranslationBundle\Model\TranslationInterface;
class Product implements TranslationInterface
{
// ...
private $translations;
}
Mark Entities as Translatable:
Implement TranslationInterface and define getTranslations()/setTranslations().
class Article implements TranslationInterface
{
public function getTranslations()
{
return $this->translations;
}
}
Database Schema:
Use the bundle’s Doctrine event listeners to auto-generate translation tables (e.g., article_translation).
# config/packages/doctrine.yaml
doctrine:
orm:
mappings:
sonata_translation:
type: attribute
dir: "%kernel.project_dir%/vendor/awaresoft/sonata-translation-bundle/Resources/config/doctrine"
prefix: 'Awaresoft\SonataTranslationBundle\Model'
Form Integration:
Extend AbstractType to handle translations:
use Awaresoft\SonataTranslationBundle\Form\Type\TranslationType;
$builder->add('translations', TranslationType::class, [
'locales' => ['en', 'fr'],
'entry_type' => ArticleTranslationType::class,
]);
Admin Panel (SonataAdmin): Enable translations in your admin class:
protected function configureFields(FieldMap $fields)
{
$fields->add('translations', 'sonata_type_translatable', [
'locales' => ['en', 'fr'],
]);
}
sonata_translation.yaml:
sonata_translation:
fallback_locale: en
LocaleListener to switch locales mid-request:
$this->get('sonata_translation.locale_listener')->setLocale('fr');
use Symfony\Component\Validator\Constraints as Assert;
$builder->add('translations', TranslationType::class, [
'entry_options' => [
'constraints' => [
new Assert\NotBlank(),
],
],
]);
Doctrine Event Conflicts:
services.yaml:
services:
Awaresoft\SonataTranslationBundle\EventListener\Doctrine\TranslationLifecycleListener: ~
Locale-Specific Queries:
if (!$entity->getTranslation($locale)) {
return $entity->getTranslation($fallbackLocale);
}
Symlink Breakage:
php bin/console cache:clear
composer dump-autoload
Symfony 4+ Compatibility:
SonataTranslationBundle to extend Bundle (not ContainerAwareBundle).resources/config/services.yaml.Missing Translations:
translations association is mapped in Doctrine:
/**
* @ORM\OneToMany(targetEntity="Translation", mappedBy="translatable")
*/
private $translations;
var/log/dev.log (e.g., missing foreign keys).Locale Not Switching:
LocaleListener is enabled in kernel.event_subscribers:
public static $subscribedEvents = [
KernelEvents::REQUEST => ['onKernelRequest', 16],
];
Custom Translation Storage:
Override the TranslationManager to use a custom driver (e.g., Redis):
class CustomTranslationManager extends TranslationManager
{
public function findTranslation($id, $locale)
{
// Custom logic
}
}
Register it in services.yaml:
services:
sonata_translation.manager:
class: App\Service\CustomTranslationManager
arguments: ['@doctrine.orm.entity_manager']
Translation Events:
Listen for sonata_translation.pre_save/post_save:
use Awaresoft\SonataTranslationBundle\Event\TranslationEvent;
$dispatcher->addListener(TranslationEvent::PRE_SAVE, function (TranslationEvent $event) {
// Pre-save logic (e.g., sanitize content)
});
Admin Customization:
Extend the TranslationAdmin class to add fields or actions:
class CustomTranslationAdmin extends TranslationAdmin
{
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper->add('custom_field');
}
}
How can I help you explore Laravel packages today?