Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Translation Bundle Laravel Package

sonata-project/translation-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require sonata-project/translation-bundle
    

    Enable the bundle in config/bundles.php:

    SonataProject\TranslationBundle\SonataTranslationBundle::class => ['all' => true],
    
  2. Configure Locales (config/packages/sonata_translation.yaml):

    sonata_translation:
        locales: [en, fr, es]
        default_locale: en
        use_gedmo: true  # or false for knplabs
        use_knplabs: false
    
  3. First Use Case:

    • For Gedmo: Add Gedmo\Translatable\Translatable to your entity and configure TranslatableListener in config/packages/doctrine.yaml:
      gedmo_listener:
          translatable: true
      
    • For KnpLabs: Add Knp\DoctrineBehaviors\Contract\Entity\TranslatableInterface to your entity and configure TranslatableBehavior in config/packages/doctrine.yaml:
      knp_gedmo:
          doctrine_behaviors:
              translatable: true
      
  4. Locale Switching: Use the locale_switcher block in Twig:

    {{ render(controller('SonataTranslationBundle:Block:localeSwitcher')) }}
    

Implementation Patterns

Core Workflows

1. Entity Translation

  • Gedmo:
    use Gedmo\Mapping\Annotation as Gedmo;
    
    #[Gedmo\Translatable]
    class Product
    {
        #[Gedmo\Translatable(fields={"name", "description"})]
        private string $name;
    
        #[Gedmo\Translatable(fields={"description"})]
        private string $description;
    }
    
  • KnpLabs:
    use Knp\DoctrineBehaviors\Contract\Entity\TranslatableInterface;
    
    class Product implements TranslatableInterface
    {
        private string $name;
        private string $description;
    }
    

2. Admin Integration (SonataAdmin)

  • Extend AbstractTranslatableAdmin for SonataAdmin:
    use Sonata\TranslationBundle\Admin\AbstractTranslatableAdmin;
    
    class ProductAdmin extends AbstractTranslatableAdmin
    {
        protected function configureFormFields(FormMapper $formMapper)
        {
            $formMapper
                ->add('name')
                ->add('description');
        }
    }
    

3. Locale-Aware Routing

  • Use RequestLocaleProvider to dynamically set locale from URL:
    # config/routes.yaml
    sonata_translation_locale:
        path: /{_locale}
        defaults: { _locale: '%locale%' }
        requirements:
            _locale: '%sonata_translation.locales%'
    

4. Translation Management

  • Use the TranslationChecker to validate translations:
    use Sonata\TranslationBundle\Checker\TranslationChecker;
    
    $checker = $container->get(TranslationChecker::class);
    $errors = $checker->check($entity);
    

5. Twig Integration

  • Access current locale in Twig:
    {{ app.request.locale }}
    
  • Translate strings:
    {{ 'product.name'|trans }}
    

Integration Tips

1. Symfony Flex Recipes

  • Use sonata-project/translation-bundle recipe for quick setup:
    composer require sonata-project/translation-bundle --with-all-dependencies
    

2. Custom Locale Provider

  • Implement LocaleProviderInterface for custom logic:
    use Sonata\TranslationBundle\Provider\LocaleProviderInterface;
    
    class CustomLocaleProvider implements LocaleProviderInterface
    {
        public function getLocale(): string
        {
            return 'custom_locale';
        }
    }
    
    Register as a service:
    services:
        App\Provider\CustomLocaleProvider:
            tags: ['sonata.translation.locale_provider']
    

3. Translation Blocks

  • Add locale switcher block to layouts:
    {% block sonata_block %}
        {{ render(controller('SonataTranslationBundle:Block:localeSwitcher')) }}
    {% endblock %}
    

4. API Translations

  • Use Locale context in API Platform:
    # config/packages/api_platform.yaml
    api_platform:
        formats:
            jsonld:
                mime_types: ['application/ld+json']
                context: '@api/contexts/translation'
    

5. Testing

  • Mock LocaleProvider in tests:
    $this->container->set('sonata.translation.locale_provider', $mockProvider);
    

Gotchas and Tips

Pitfalls

1. Locale Configuration Conflicts

  • Issue: You have requested a non-existent parameter "locale".
  • Fix: Ensure default_locale is set in sonata_translation.yaml and matches a valid locale in the locales array.

2. Gedmo vs. KnpLabs Incompatibility

  • Issue: Mixing Gedmo and KnpLabs behaviors causes conflicts.
  • Fix: Stick to one library per project. Configure use_gedmo or use_knplabs (not both) in sonata_translation.yaml.

3. Translatable Listener Not Registered

  • Issue: Translations not saved.
  • Fix: Explicitly configure the listener service:
    sonata_translation:
        gedmo:
            translatable_listener_service: gedmo.listener.translatable
    

4. Deprecated Interfaces

  • Issue: Using Sonata\TranslationBundle\Model\TranslatableInterface (deprecated).
  • Fix: Replace with Gedmo\Translatable\Translatable or Knp\DoctrineBehaviors\Contract\Entity\TranslatableInterface.

5. Locale Switcher Block Not Rendering

  • Issue: Blank space where the locale switcher should be.
  • Fix: Ensure the block is registered in sonata_block.yaml:
    blocks:
        sonata.translation.locale_switcher:
            class: Sonata\TranslationBundle\Block\LocaleSwitcherBlock
            settings:
                locales: ['en', 'fr', 'es']
    

Debugging Tips

1. Check Locale Provider

  • Dump the active provider:
    $provider = $container->get('sonata.translation.locale_provider');
    dump($provider->getLocale());
    

2. Validate Entity Translations

  • Use the TranslationChecker:
    $checker = $container->get(TranslationChecker::class);
    $errors = $checker->check($entity);
    dump($errors);
    

3. Enable Doctrine Logging

  • Add to config/packages/dev/doctrine.yaml:
    doctrine:
        dbal:
            logging: true
            profiling: true
    

4. Clear Cache After Configuration Changes

  • Run:
    php bin/console cache:clear
    

Extension Points

1. Custom Translation Listener

  • Extend Gedmo\Translatable\TranslatableListener or Knp\DoctrineBehaviors\Model\TranslatableListener:
    use Gedmo\Translatable\TranslatableListener;
    
    class CustomTranslatableListener extends TranslatableListener
    {
        public function preFlush(UnitOfWork $uow): void
        {
            // Custom logic
            parent::preFlush($uow);
        }
    }
    
    Register as a service:
    services:
        App\Listener\CustomTranslatableListener:
            tags:
                - { name: doctrine.event_listener, event: preFlush }
    

2. Override Twig Extensions

  • Extend SonataTranslationBundle's Twig extensions:
    use Sonata\TranslationBundle\Twig\TranslationExtension;
    
    class CustomTranslationExtension extends TranslationExtension
    {
        public function getTranslatedString($id, array $parameters = [], $domain = null, $locale = null)
        {
            // Custom logic
            return parent::getTranslatedString($id, $parameters, $domain, $locale);
        }
    }
    
    Override in config/packages/twig.yaml:
    twig:
        globals:
            trans: '@App\Twig\CustomTranslationExtension'
    

3. Custom Locale Switcher Block

  • Extend LocaleSwitcherBlock:
    use Sonata\TranslationBundle\Block\LocaleSwitcherBlock;
    
    class CustomLocaleSwitcherBlock extends LocaleSwitcherBlock
    {
        public function executeView(Template $template)
        {
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor