baconmanager/translation-form-bundle
Install Dependencies
composer require a2lix/translation-form-bundle baconmanager/translation-form-bundle
Register Bundles in app/AppKernel.php:
new A2lix\TranslationFormBundle\A2lixTranslationFormBundle(),
new BaconManager\TranslationFormBundle\BaconTranslationFormBundle(),
Configure config.yml:
a2lix_translation_form:
locale_provider: locale_doctrine_provider
locales: [en_US, pt_BR] # Optional if using dynamic provider
default_locale: en_US
manager_registry: doctrine
templating: "BaconTranslationFormBundle::default.html.twig"
bacon_translation_form:
class_language_provider: AppBundle\Entity\Language # Your custom Language entity
First Use Case
Create a translatable entity (e.g., Product) with Translation embeddable and implement the bundle’s interfaces for your Language entity and repository as shown in the README.
Entity Setup
Extend A2lix\TranslationFormBundle\Model\TranslatableInterface for your main entity (e.g., Product).
Use A2lix\TranslationFormBundle\Model\Translation as an embeddable for translations.
Language Provider
Implement Bacon\Bundle\TranslationFormBundle\Locale\EntityInterface for your Language entity (e.g., AppBundle\Entity\Language).
Implement Bacon\Bundle\TranslationFormBundle\Locale\RepositoryInterface for the repository (e.g., AppBundle\Entity\Repository\LanguageRepository) with getAllLocale().
Form Type
Use A2lix\TranslationFormBundle\Form\Type\TranslationsType in your form builder:
$builder->add('translations', TranslationsType::class, [
'fields' => ['name', 'description'], // Fields to translate
'locales' => ['en_US', 'pt_BR'], // Optional if using dynamic provider
]);
Twig Rendering Use the bundle’s Twig function to display language tabs:
{{ render_language_tab(language, 'product.translations') }}
Saving Translations
The EventListener (Bacon\Bundle\TranslationFormBundle\EventListener\TranslationListener) automatically tracks added/updated locales for each translatable entity.
getAllLocale() from your repository to fetch locales dynamically, avoiding hardcoded locales in config.useResultCache in getAllLocale() to optimize performance (as shown in the example).A2C\Bundle\CoreBundle\Entity\BaseEntity for your Language entity to reuse common traits (e.g., timestamps, slugs).Language entity (e.g., @Assert\Length for locale/acron fields).Locale Provider Mismatch
locale_provider: locale_doctrine_provider in a2lix_translation_form config matches the bundle’s expectations.A2lix\TranslationFormBundle\Provider\LocaleProviderInterface.Entity/Repository Interfaces
EntityInterface or RepositoryInterface will cause runtime errors. Double-check:
use Bacon\Bundle\TranslationFormBundle\Locale\EntityInterface;
use Bacon\Bundle\TranslationFormBundle\Locale\RepositoryInterface;
Caching Issues
md5('bacon_cache_locale_provider') in getAllLocale() is hardcoded. Change it if you update your cache strategy (e.g., use a config parameter).Twig Template Path
BaconTranslationFormBundle::default.html.twig) must exist. Override it in config if needed:
templating: "YourBundle::custom/translation.html.twig"
Event Listener Activation
TranslationListener is auto-registered but requires the KnpDoctrineBehaviorsBundle (listed in AppKernel.php). Skip this bundle if you don’t need it.Check Locale Provider Dump the provider in a controller to verify it returns expected locales:
$provider = $this->get('a2lix_translation_form.locale_provider');
dump($provider->getLocales());
Form Debugging Enable form theme debugging in Twig:
{% form_theme _self with {'debug': true} %}
Doctrine Events
Listen for prePersist/preUpdate events to debug translation tracking:
$entityManager->getEventManager()->addEventListener(
[ORM\Events::prePersist, ORM\Events::preUpdate],
function ($event) {
dump($event->getEntity());
}
);
Custom Twig Functions
Extend the bundle’s Twig functions by overriding the template or adding new ones in your bundle’s Resources/views:
{% macro render_custom_tab(language) %}
<li>{{ language.acron }}</li>
{% endmacro %}
Locale Filtering
Modify getAllLocale() to filter active/inactive languages:
public function getAllLocale() {
$qb = $this->createQueryBuilder('l')
->where('l.isActive = :active')
->setParameter('active', true);
return $qb->getQuery()->getResult();
}
Translation Validation
Add custom validation to the Translation embeddable:
use Symfony\Component\Validator\Constraints as Assert;
/**
* @Assert\NotBlank(groups={"translation_validation"})
*/
private $title;
Event Subscribers
Extend the TranslationListener to add custom logic (e.g., logging):
public function postPersist(LifecycleEventArgs $args) {
$entity = $args->getObject();
if ($entity instanceof TranslatableInterface) {
$this->logger->info('Translations saved for ' . get_class($entity));
}
}
How can I help you explore Laravel packages today?