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

cvele/translation-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the bundle to your composer.json:

    composer require cvele/translation-bundle
    

    Register the bundle in config/bundles.php (Symfony) or config/app.php (Laravel via Symfony bridge):

    return [
        // ...
        SchmittJoh\JMSTranslationBundle\JMSTranslationBundle::class => ['all' => true],
    ];
    
  2. Configuration Publish the default config:

    php artisan vendor:publish --tag=jms-translation-config
    

    Update config/packages/jms_translation.yaml (or config/jms_translation.php if using Laravel's YAML-to-PHP adapter).

  3. First Use Case Translate a message in a controller or Blade template:

    // Symfony
    $this->get('translator')->trans('message.key', ['%name%' => 'John']);
    
    // Laravel (via Symfony bridge)
    $translator = app('translator');
    echo $translator->trans('message.key', ['%name%' => 'John']);
    

Implementation Patterns

Core Workflows

  1. Translation Domains Use domains to isolate translations (e.g., admin, frontend):

    # config/packages/jms_translation.yaml
    jms_translation:
        configs:
            admin:
                dirs: ['%kernel.project_dir%/translations/admin']
                output_dir: '%kernel.project_dir%/var/cache/admin'
    

    Access via:

    $translator->transChoice('admin.message', 1, ['%count%' => 1], 'admin');
    
  2. Pluralization & Choice Handling Leverage Symfony’s transChoice for dynamic pluralization:

    $translator->transChoice('messages.new', $count, ['%count%' => $count]);
    

    Define translations in messages.en.yaml:

    messages:
        new:
            0: "No new messages"
            1: "One new message"
            %d: "%count% new messages"
    
  3. Translation Extraction Automate extraction from PHP/Blade:

    php artisan jms:translation:extract
    

    Configure extraction paths in config/packages/jms_translation.yaml:

    jms_translation:
        extractors:
            php:
                dirs: ['src']
            twig:
                dirs: ['templates']
    
  4. Caching & Performance Enable caching for compiled translations:

    jms_translation:
        file_cache_dir: '%kernel.cache_dir%/translations'
    

    Clear cache after updates:

    php artisan cache:clear
    
  5. Laravel-Specific Integration Bind the translator to Laravel’s service container (if not using Symfony bridge):

    // config/app.php
    'providers' => [
        // ...
        SchmittJoh\JMSTranslationBundle\JMSTranslationBundle::class,
    ],
    

    Use in Blade:

    {{ trans('message.key', ['%var%' => $value]) }}
    

Gotchas and Tips

Pitfalls

  1. Namespace Conflicts Ensure translation keys are namespaced (e.g., admin.user.profile) to avoid collisions. Use domains for logical grouping.

  2. Extractor Configuration Misconfigured extractors may miss translations. Verify dirs paths in jms_translation.yaml and test extraction:

    php artisan jms:translation:extract --dry-run
    
  3. Caching Quirks

    • Clear cache after adding new translations or domains:
      php artisan cache:clear
      
    • Avoid editing cached files directly; regenerate via:
      php artisan jms:translation:compile
      
  4. Laravel-Symfony Bridge Issues

    • If using Laravel’s Symfony bridge, ensure translator service is properly bound:
      $this->app->singleton('translator', function ($app) {
          return new \Symfony\Component\Translation\Translator(
              $app['config']['app.locale'],
              new \SchmittJoh\JMSTranslationBundle\Translation\Loader\YamlFileLoader(
                  $app['kernel']->getProjectDir() . '/translations'
              )
          );
      });
      
    • Prefer Laravel’s native trans() helper for simplicity unless advanced features are needed.
  5. Pluralization Rules

    • Default rules may not match all languages. Override in config/packages/jms_translation.yaml:
      jms_translation:
          pluralization:
              rules:
                  en: "n % 10 == 1 && n % 100 != 11 ? 1 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 2 : 0"
      

Debugging Tips

  1. Translation Not Found

    • Verify the translation file exists in the configured dirs.
    • Check for typos in keys (case-sensitive).
    • Use translator->getCatalogue()->all() to inspect loaded translations.
  2. Extractor Skipping Files

    • Ensure files have the correct extension (e.g., .php, .twig).
    • Add debug output in extractors by extending the base class and logging skipped files.
  3. Performance Bottlenecks

    • Profile translation loading with Xdebug or Blackfire.
    • Disable unused domains in jms_translation.yaml to reduce memory usage.

Extension Points

  1. Custom Extractors Create a custom extractor by implementing SchmittJoh\JMSTranslationBundle\Extractor\ExtractorInterface:

    class CustomExtractor implements ExtractorInterface {
        public function extract($file, $locale, LoaderInterface $loader) {
            // Custom logic to parse files (e.g., JSON, XML)
            return ['key' => 'value'];
        }
    }
    

    Register in config:

    jms_translation:
        extractors:
            custom:
                class: App\Extractor\CustomExtractor
                dirs: ['custom/path']
    
  2. Dynamic Translation Loading Load translations dynamically at runtime:

    $loader = $translator->getLoader();
    $loader->load('dynamic', 'en', new \ArrayLoader(['key' => 'Dynamic Value']));
    
  3. Middleware for Locale Switching Use middleware to set the locale based on headers/URL:

    public function handle($request, Closure $next) {
        $locale = $request->get('locale', config('app.locale'));
        app('translator')->setLocale($locale);
        return $next($request);
    }
    
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.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
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