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

Xliff Laravel Package

elasticms/xliff

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require elasticms/xliff
    

    Ensure your project uses PHP 8.x and Laravel 10+.

  2. First Use Case: Export a Laravel model to XLIFF for translation:

    use Elasticms\Xliff\Xliff;
    
    $posts = Post::all()->toArray();
    $xliff = Xliff::create('en', 'fr', $posts);
    $xliff->save('path/to/translations.xlf');
    
  3. Where to Look First:

    • Documentation for API reference.
    • src/Xliff.php for core methods (create(), load(), save()).
    • Test files (if available) for edge-case examples.

Implementation Patterns

Usage Patterns

  1. Export Workflow:

    • Model to XLIFF:
      $data = Post::with('translations')->get()->toArray();
      $xliff = Xliff::create('source_locale', 'target_locale', $data, [
          'file_format' => 'xliff2', // or 'xliff1'
          'segment_html' => true,    // preserve HTML structure
      ]);
      $xliff->save(storage_path('app/translations.xlf'));
      
    • Trigger on Model Events:
      Post::observe(PostObserver::class);
      
      // app/Observers/PostObserver.php
      class PostObserver {
          public function saved(Post $post) {
              if ($post->isDirty('content')) {
                  $this->exportTranslations($post);
              }
          }
      
          protected function exportTranslations(Post $post) {
              $xliff = Xliff::create('en', 'es', [$post->toArray()]);
              $xliff->save("storage/translations/{$post->id}.xlf");
          }
      }
      
  2. Import Workflow:

    • XLIFF to Database:
      $xliff = Xliff::load(storage_path('app/translations.xlf'));
      foreach ($xliff->getTranslations() as $translation) {
          $post = Post::find($translation['id']);
          $post->update([
              'content' => $translation['target']['content'],
          ]);
      }
      
  3. HTML Segmentation:

    • Enable for rich-text fields:
      $xliff = Xliff::create('en', 'fr', $posts, [
          'segment_html' => true,
          'html_tags' => ['p', 'strong', 'em'], // customize allowed tags
      ]);
      
  4. Artisan Commands:

    • Bulk export/import:
      php artisan xliff:export posts en fr
      php artisan xliff:import storage/translations.xlf
      
    • Register in app/Console/Kernel.php:
      protected $commands = [
          \Elasticms\Xliff\Console\ExportCommand::class,
          \Elasticms\Xliff\Console\ImportCommand::class,
      ];
      

Integration Tips

  • Laravel Service Provider: Bind the XLIFF service for dependency injection:

    // app/Providers/XliffServiceProvider.php
    public function register() {
        $this->app->singleton('xliff', function () {
            return new \Elasticms\Xliff\Xliff();
        });
    }
    
  • Blade Directives: Create a custom Blade directive to fetch translations:

    // app/Providers/BladeServiceProvider.php
    Blade::directive('translate', function ($locale) {
        return "<?php echo app('xliff')->getTranslation($locale); ?>";
    });
    

    Usage:

    <h1>@translate('es')</h1>
    
  • Queue Jobs: Offload large exports/imports:

    // app/Jobs/ExportTranslationsJob.php
    public function handle() {
        $xliff = Xliff::create('en', 'fr', $this->posts);
        $xliff->save($this->path);
    }
    

    Dispatch:

    ExportTranslationsJob::dispatch($posts, 'storage/translations.xlf')->onQueue('xliff');
    
  • Translation Fallback: Combine with Laravel’s localization:

    $fallback = trans('messages.welcome');
    $xliffTranslation = app('xliff')->getTranslation('es', 'messages.welcome');
    echo $xliffTranslation ?? $fallback;
    

Gotchas and Tips

Pitfalls

  1. XML Memory Limits:

    • Large XLIFF files (>10MB) may hit PHP’s memory_limit. Mitigate by:
      • Chunking exports: Process models in batches of 100.
      • Using XMLWriter for streaming:
        $writer = new XMLWriter();
        $writer->openMemory();
        $writer->startDocument('1.0', 'UTF-8');
        // Stream segments incrementally
        
  2. HTML Parsing Quirks:

    • Unclosed Tags: XLIFF may fail on malformed HTML. Validate with:
      $dom = new DOMDocument();
      $dom->loadHTML($html);
      $cleanHtml = $dom->saveHTML();
      
    • Script/Style Tags: Exclude from segmentation if not needed:
      $xliff = Xliff::create('en', 'fr', $data, [
          'html_tags' => ['p', 'span', 'div'], // exclude 'script', 'style'
      ]);
      
  3. Locale Handling:

    • Invalid Locales: XLIFF 2.2 requires valid BCP 47 locales (e.g., en-US). Sanitize with:
      use Symfony\Component\Intl\Locales;
      $locale = Locales::getName($inputLocale);
      
    • Fallback Logic: Ensure translations fall back to the source locale:
      $translation = app('xliff')->getTranslation('es', 'key') ?: app('xliff')->getTranslation('en', 'key');
      
  4. Namespace Conflicts:

    • If using elasticms elsewhere, alias the package:
      use Elasticms\Xliff as XliffPackage;
      
  5. XLIFF Version Mismatches:

    • XLIFF 1.2 vs. 2.2: Some translation tools enforce specific versions. Test with:
      $xliff = Xliff::create('en', 'fr', $data, ['file_format' => 'xliff2']);
      

Debugging

  • Validate XLIFF Output: Use online validators like XML Validation or CLI:

    xmllint --noout translations.xlf
    
  • Log Errors: Wrap XLIFF operations in try-catch:

    try {
        $xliff->save($path);
    } catch (\Elasticms\Xliff\Exception $e) {
        Log::error('XLIFF export failed: ' . $e->getMessage());
        throw $e;
    }
    
  • Check for Empty Segments: XLIFF may skip empty <source> or <target> tags. Add validation:

    if (empty($segment['source'])) {
        throw new \InvalidArgumentException('Source text cannot be empty.');
    }
    

Tips

  1. Custom Metadata: Add project-specific notes to XLIFF files:

    $xliff = Xliff::create('en', 'fr', $data, [
        'metadata' => [
            'project' => 'MyApp',
            'due_date' => '2024-12-31',
        ],
    ]);
    
  2. Context-Specific Translations: Use XLIFF’s <context> or <group> for disambiguation:

    $data = [
        'title' => [
            'context' => 'homepage',
            'value' => 'Welcome',
        ],
    ];
    
  3. Performance Optimization:

    • Cache XLIFF exports for unchanged content:
      if (!$post->isDirty('content') && cache()->has("xliff_{$post->id}")) {
          return cache()->get("xliff_{$post->id}");
      }
      
    • Use SimpleXML for faster parsing (if supported):
      $xliff = simplexml_load_file($path);
      
  4. Testing:

    • Mock XLIFF files for unit tests:
      $mockXliff = <<<'XML'
      <?xml version="1.0"?>
      <xliff version="2.2" xmlns="urn:oasis:names:tc:xliff:document:2.2
      
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
andydefer/laravel-cluster
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