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

Translator Bundle Laravel Package

atoolo/translator-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Bundle

    composer require atoolo/translator-bundle
    

    Enable in config/bundles.php:

    return [
        // ...
        Atoolo\TranslatorBundle\AtooloTranslatorBundle::class => ['all' => true],
    ];
    
  2. Configure the Service Edit config/packages/atoolo_translator.yaml:

    atoolo_translator:
        api_key: '%env(ATOOLO_API_KEY)%'  # Replace with your DeepL/API key
        service: 'deepl'                   # Supported: 'deepl', 'custom'
        cache:
            enabled: true
            pool: 'cache.app'             # Symfony cache pool
        default_locale: 'en'
        target_locales: ['de', 'fr']      # Add your target locales
    
  3. First Translation Inject the translator service in a controller or command:

    use Atoolo\TranslatorBundle\Service\TranslatorService;
    
    public function __construct(private TranslatorService $translator) {}
    
    public function translateText(): string
    {
        $text = 'Hello, world!';
        $translation = $this->translator->translate($text, 'de');
        return $translation; // Returns cached or freshly translated text
    }
    

Key First Use Case

Translate a dynamic string (e.g., user-generated content) in a Symfony controller:

$translated = $this->translator->translate($userInput, $targetLocale);
$this->renderTemplate('page.html.twig', ['translatedText' => $translated]);

Implementation Patterns

Core Workflow

  1. Translation Request Use the TranslatorService to fetch translations:

    $translator->translate('Source text', 'de'); // Returns cached or fresh translation
    
  2. Batch Processing For bulk translations (e.g., CMS content):

    $batch = [
        ['text' => 'Home', 'locale' => 'de'],
        ['text' => 'About', 'locale' => 'fr'],
    ];
    $results = $translator->translateBatch($batch);
    
  3. Integration with Symfony Forms Add a TranslationType to forms for dynamic field labels:

    use Atoolo\TranslatorBundle\Form\Type\TranslationType;
    
    $builder->add('title', TranslationType::class, [
        'source' => 'default_title',
        'locales' => ['de', 'fr'],
    ]);
    

Advanced Patterns

  • Custom Services Extend Atoolo\TranslatorBundle\Service\AbstractTranslator for non-DeepL providers (e.g., Google Translate):

    class GoogleTranslator extends AbstractTranslator {
        public function translate(string $text, string $targetLocale): string {
            // Custom logic
        }
    }
    

    Register in config/services.yaml:

    services:
        App\Service\GoogleTranslator:
            tags: ['atoolo_translator.provider']
    
  • Cache Invalidation Clear translations manually (e.g., after content updates):

    $this->translator->invalidateCache('de'); // Invalidate for a locale
    $this->translator->invalidateCacheAll(); // Clear all caches
    
  • Event Listeners Hook into translation events (e.g., log failed translations):

    use Atoolo\TranslatorBundle\Event\TranslationFailedEvent;
    
    $eventDispatcher->addListener(TranslationFailedEvent::class, function (TranslationFailedEvent $event) {
        // Log or retry logic
    });
    

Gotchas and Tips

Common Pitfalls

  1. API Key Leaks

    • Risk: Hardcoding api_key in config exposes credentials.
    • Fix: Use Symfony’s %env() and validate in .env:
      ATOOLO_API_KEY=%env(ATOOLO_API_KEY)%  # Never commit .env
      
    • Tip: Use symfony/dotenv to load keys from .env.local.
  2. Cache Staleness

    • Issue: Cached translations may not reflect updates from the source service.
    • Solution: Implement a TTL (Time-To-Live) in cache config:
      cache:
          enabled: true
          pool: 'cache.app'
          ttl: 3600  # 1 hour (default: 86400)
      
    • Workaround: Use invalidateCache() after bulk updates.
  3. Locale Mismatches

    • Problem: Translating to unsupported locales (e.g., 'xx').
    • Fix: Validate locales in config:
      target_locales: ['de', 'fr']  # Explicitly list supported locales
      
    • Tip: Add a LocaleValidator service to reject invalid locales early.
  4. Rate Limiting

    • Issue: External APIs (e.g., DeepL) throttle requests.
    • Mitigation:
      • Use batch processing for large datasets.
      • Implement exponential backoff in custom providers:
        $client->setOptions(['delay' => 1000]); // 1-second delay between requests
        

Debugging Tips

  • Enable Verbose Logging Configure Monolog in config/packages/monolog.yaml:

    handlers:
        translator:
            type: stream
            path: "%kernel.logs_dir%/translator.log"
            level: debug
    

    Log translation events via the TranslationEvent class.

  • Test Cache Behavior Use Symfony’s CacheClearer to simulate cache misses:

    php bin/console cache:clear
    

    Or manually clear the pool:

    $cachePool = $this->container->get('cache.app');
    $cachePool->clear();
    

Extension Points

  1. Custom Providers

    • Implement Atoolo\TranslatorBundle\Service\TranslatorInterface for new services (e.g., Azure Translator).
    • Tag the service in services.yaml:
      tags: ['atoolo_translator.provider']
      
  2. Pre/Post-Translation Hooks Extend AbstractTranslator to modify text before/after translation:

    class CustomTranslator extends AbstractTranslator {
        protected function preTranslate(string $text): string {
            return strtoupper($text); // Example: Force uppercase
        }
    }
    
  3. Fallback Logic Configure fallback locales in config/packages/atoolo_translator.yaml:

    fallback_locale: 'en'  # Fallback if target locale fails
    

    Override the TranslatorService to handle fallbacks:

    public function translate(string $text, string $targetLocale): string {
        try {
            return parent::translate($text, $targetLocale);
        } catch (TranslationException $e) {
            return $this->translate($text, $this->config['fallback_locale']);
        }
    }
    

Performance Quirks

  • Cache Pool Selection

    • Use cache.app for short-lived translations (e.g., user input).
    • Use cache.system for long-lived translations (e.g., static content).
    • Warning: Avoid cache.doctrine (ORM-specific).
  • Batch Size Limits

    • DeepL’s API has a 5000-character limit per request. Split long texts:
      $translator->translateChunked($longText, 'de', 4000); // Custom method
      
  • Parallel Requests

    • Disable parallel requests in config/packages/atoolo_translator.yaml if the API blocks IPs:
      parallel_requests: false
      
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.
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager