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

Symfony Bundle I18N Laravel Package

binsoul/symfony-bundle-i18n

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require binsoul/symfony-bundle-i18n
    

    Ensure the bundle is enabled in config/bundles.php (Symfony 4+ auto-discovers it).

  2. Load Fixtures:

    php bin/console doctrine:fixtures:load --group=binsoul/symfony-bundle-i18n
    

    This populates the Locale and Translation tables (if using Doctrine).

  3. First Use Case:

    • Route-based localization: Add %locale% to your routes (e.g., /{_locale}/products).
    • Twig integration: Use {{ 'key'|trans }} in templates. Ensure translator is configured in config/packages/binsoul_i18n.yaml.

Where to Look First

  • Configuration: config/packages/binsoul_i18n.yaml (default fallback locale, supported locales, etc.).
  • Entities: src/Entity/Locale.php and src/Entity/Translation.php (if extending).
  • Services: src/DependencyInjection/Configuration.php for customization hooks.

Implementation Patterns

Core Workflows

  1. Dynamic Locale Switching:

    • Use the LocaleListener to detect locale from:
      • Route parameter (_locale).
      • Subdomain (e.g., en.example.com).
      • Accept-Language header (fallback).
    • Example route:
      # config/routes.yaml
      products:
        path: /{_locale}/products
        controller: App\Controller\ProductController::index
        requirements:
          _locale: en|fr|es
      
  2. Translation Management:

    • Database-backed translations: Store translations in Translation entity (useful for admin-editable content).
      // Add a translation to a product
      $translation = new Translation();
      $translation->setLocale('fr');
      $translation->setContent('Contenu traduit');
      $translation->setTranslatable($product); // Polymorphic relation
      $entityManager->persist($translation);
      
    • Fallback chain: Configure fallback locales in config/packages/binsoul_i18n.yaml:
      fallback_locales:
        fr: en
        es: en
      
  3. Twig Extensions:

    • Use trans filter for dynamic content:
      {{ product.name|trans }}
      
    • Access current locale:
      {{ app.request.locale }}
      
  4. Form Localization:

    • Extend AbstractType to handle locale-aware forms:
      public function configureOptions(OptionsResolver $resolver)
      {
          $resolver->setDefaults([
              'locale' => $this->getCurrentLocale(), // Inject via constructor
          ]);
      }
      

Integration Tips

  • Doctrine Events: Listen for prePersist/preUpdate to auto-generate translations for entities:
    $entityManager->getEventManager()->addEventListener(
        [YourEntity::class],
        new TranslationLifecycleListener()
    );
    
  • APIs: Use RequestStack to access locale in controllers:
    $locale = $this->get('request_stack')->getCurrentRequest()->getLocale();
    
  • Testing: Mock the LocaleListener to test locale-specific behavior:
    $this->container->get('binsoul_i18n.locale_listener')->setLocale('fr');
    

Gotchas and Tips

Pitfalls

  1. Locale Detection Order:

    • The bundle checks routes first, then subdomains, then headers. Override LocaleListener if this order doesn’t fit your needs:
      // src/EventListener/CustomLocaleListener.php
      public function onKernelRequest(GetResponseEvent $event)
      {
          $request = $event->getRequest();
          $locale = $request->get('lang', $request->getPreferredLanguage()); // Custom logic
          $this->setLocale($locale);
      }
      
  2. Caching Translations:

    • Database-backed translations aren’t cached by default. Use TranslationReader with a cache layer:
      $reader = new DoctrineTranslationReader($entityManager);
      $reader->setCache($cache); // Psr\Cache\CacheItemPoolInterface
      
  3. Route Requirements:

    • Forgetting to add _locale to route requirements will break locale switching:
      # WRONG: Missing requirements
      path: /{locale}/products
      
      # CORRECT
      path: /{_locale}/products
      requirements:
        _locale: en|fr
      
  4. Fallback Locale Conflicts:

    • If fallback_locales isn’t configured, missing translations will throw TranslationNotFoundException. Always define a fallback (e.g., en).

Debugging

  • Check Current Locale:
    php bin/console debug:container binsoul_i18n.locale_listener | grep locale
    
  • Log Locale Switches: Add a subscriber to log locale changes:
    public function onKernelRequest(GetResponseEvent $event)
    {
        $this->logger->info('Locale set to: ' . $event->getRequest()->getLocale());
    }
    

Extension Points

  1. Custom Locale Providers:

    • Implement LocaleProviderInterface for non-standard sources (e.g., user preferences):
      class UserPreferenceLocaleProvider implements LocaleProviderInterface
      {
          public function getLocale(Request $request): string
          {
              return $request->getUser()->getPreferredLocale();
          }
      }
      
    • Register in config/packages/binsoul_i18n.yaml:
      locale_providers:
          - binsoul_i18n.locale_provider.route
          - app.user_preference_locale_provider
      
  2. Translation Sources:

    • Extend TranslationReaderInterface to support additional sources (e.g., API calls):
      class ApiTranslationReader implements TranslationReaderInterface
      {
          public function getTranslation(string $id, string $locale): string
          {
              return $this->apiClient->fetchTranslation($id, $locale);
          }
      }
      
  3. Event Dispatching:

    • Listen for binsoul_i18n.locale_changed to trigger side effects (e.g., redirect, cache flush):
      $dispatcher->addListener(
          'binsoul_i18n.locale_changed',
          function (LocaleChangedEvent $event) {
              // Clear cache for the new locale
          }
      );
      

Configuration Quirks

  • Default Locale:
    • Set in config/packages/binsoul_i18n.yaml:
      default_locale: en
      
    • Override globally in AppKernel (Symfony <5):
      $kernel->setLocale('fr');
      
  • Supported Locales:
    • Define explicitly to avoid runtime errors:
      supported_locales:
        - en
        - fr
        - es
      
    • Use * for dynamic locales (but validate manually).

Performance Tips

  • Batch Translation Loading:
    • Use TranslationRepository::findByTranslatable() with DISTINCT to avoid N+1 queries:
      $translations = $repository->findByTranslatable($entity, ['locale' => $locale]);
      
  • Lazy-Loading:
    • For large datasets, implement LazyTranslationLoader to fetch translations on-demand.
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.
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity
testo/bridge-symfony
spatie/flare-daemon-runtime
canaltp/sam-ecore-application-manager-bundle
canaltp/sam-ecore-security-manager-bundle