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

Locale Bundle Laravel Package

lunetics/locale-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require lunetics/locale-bundle
    

    Register the bundle in config/bundles.php:

    return [
        // ...
        Lunetics\LocaleBundle\LuneticsLocaleBundle::class => ['all' => true],
    ];
    
  2. Configure Supported Locales Edit config/packages/lunetics_locale.yaml:

    lunetics_locale:
        locales: ['en', 'fr', 'de']  # Add your supported locales
        default_locale: 'en'          # Fallback locale
    
  3. First Use Case: Route-Based Locale Switching Define a route with a _locale parameter:

    # config/routes.yaml
    app_home:
        path: /{_locale}/home
        controller: App\Controller\HomeController::index
        requirements:
            _locale: en|fr|de
    

    Access via /en/home, /fr/home, etc.


Implementation Patterns

Core Workflow: Locale Detection

  1. Priority Order The bundle checks locales in this order:

    • Route parameter (_locale)
    • Subdomain (e.g., fr.example.com)
    • Browser Accept-Language header
    • Cookie (locale)
    • Session (locale)
    • Default locale (fallback)
  2. Dynamic Locale Switching Use the LocaleListener to override logic:

    // src/EventListener/CustomLocaleListener.php
    namespace App\EventListener;
    
    use Lunetics\LocaleBundle\Event\LocaleEvent;
    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    
    class CustomLocaleListener implements EventSubscriberInterface
    {
        public static function getSubscribedEvents()
        {
            return [
                'locale' => 'onLocale',
            ];
        }
    
        public function onLocale(LocaleEvent $event)
        {
            if ($event->getLocale() === 'en' && $event->getRequest()->getClientIp() === '123.45.67.89') {
                $event->setLocale('fr'); // Force override
            }
        }
    }
    
  3. Integration with Twig Access the current locale in templates:

    {{ app.request.locale }}  {# Outputs 'fr' #}
    

    Or use the locale filter:

    {{ 'Hello'|trans({% transchoice %}, {0: 'World'}) }}  {# Translates dynamically #}
    
  4. URL Generation with Locale Use the UrlGeneratorInterface to generate locale-aware URLs:

    $url = $this->router->generate('app_home', ['_locale' => 'fr']);
    // Outputs: /fr/home
    

Advanced Patterns

  1. Subdomain-Based Routing Configure subdomains in config/packages/lunetics_locale.yaml:

    lunetics_locale:
        subdomains:
            fr: 'fr'
            de: 'de'
    

    Now fr.example.com resolves to locale fr.

  2. Cookie/Session Persistence Enable cookie/session storage:

    lunetics_locale:
        cookie:
            enabled: true
            name: 'locale'
            lifetime: 31536000  # 1 year
        session:
            enabled: true
    
  3. Fallback Logic Handle unsupported locales gracefully:

    lunetics_locale:
        fallback_locale: 'en'  # Redirects invalid locales to default
    
  4. API-Specific Locale Handling Override locale detection for APIs:

    // src/EventListener/APILocaleListener.php
    public function onLocale(LocaleEvent $event)
    {
        if ($event->getRequest()->headers->get('X-API-Locale')) {
            $event->setLocale($event->getRequest()->headers->get('X-API-Locale'));
        }
    }
    

Gotchas and Tips

Pitfalls

  1. Route Parameter Conflicts

    • Ensure _locale doesn’t clash with other route parameters.
    • Use requirements to restrict allowed locales:
      _locale: en|fr|de
      
  2. Subdomain Misconfiguration

    • Subdomain routing requires a wildcard DNS (*.example.com).
    • Test with curl -H "Host: fr.example.com" http://example.com.
  3. Cookie vs. Session Conflicts

    • If both cookie and session are enabled, the cookie takes precedence.
    • Clear cookies/sessions during testing to avoid stale data.
  4. Caching Issues

    • Clear Symfony cache (php bin/console cache:clear) after changing locale configurations.
    • Ensure AppCache is disabled in dev environment if testing changes.
  5. Translation Files

    • Forgetting to create translation files (e.g., messages.fr.yaml) will result in missing translations.
    • Use php bin/console debug:translation to verify loaded locales.

Debugging Tips

  1. Log Locale Events Enable debug mode and check logs for locale events:

    # config/packages/monolog.yaml
    handlers:
        main:
            level: debug
    
  2. Inspect Request Locale Add a temporary controller to debug:

    public function debugLocale(Request $request)
    {
        return new Response(
            'Locale: ' . $request->getLocale() .
            '<br>Accept-Language: ' . $request->headers->get('Accept-Language')
        );
    }
    
  3. Override Default Behavior Temporarily disable all guessers to isolate issues:

    lunetics_locale:
        guessers:
            route: false
            subdomain: false
            browser: false
    

Extension Points

  1. Custom Guessers Implement Lunetics\LocaleBundle\Guesser\LocaleGuesserInterface:

    class IPBasedGuesser implements LocaleGuesserInterface
    {
        public function guessLocale(Request $request)
        {
            $ip = $request->getClientIp();
            if ($ip === '192.168.1.1') {
                return 'fr';
            }
            return null; // No guess
        }
    }
    

    Register in config/packages/lunetics_locale.yaml:

    lunetics_locale:
        guessers:
            ip_based: App\Guesser\IPBasedGuesser
    
  2. Event Subscribers Extend the locale event for custom logic (e.g., user-based overrides):

    public function onLocale(LocaleEvent $event)
    {
        $user = $this->get('security.token_storage')->getToken()->getUser();
        if ($user && $user->getPreferredLocale()) {
            $event->setLocale($user->getPreferredLocale());
        }
    }
    
  3. Dynamic Locale Lists Load locales from a database or API:

    $locales = $this->entityManager->getRepository(Locale::class)->findAll();
    $config['locales'] = array_map(fn($locale) => $locale->getCode(), $locales);
    

Configuration Quirks

  1. Default Locale Fallback

    • If default_locale is not set, the bundle throws an exception.
    • Ensure fallback_locale is configured if using strict validation.
  2. Cookie Security

    • Set secure: true and httponly: true for production cookies:
      lunetics_locale:
          cookie:
              secure: true
              httponly: true
      
  3. Route Priority

    • Route-based locales override all other guessers except when explicitly disabled.
  4. Case Sensitivity

    • Locale codes are case-insensitive (FR = fr), but consistency is recommended.
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