Installation (updated for 7.3.0):
composer require elasticms/xliff:^7.3
Add the service provider to config/app.php (unchanged):
'providers' => [
Elasticms\Xliff\XliffServiceProvider::class,
],
First Export (new toXliff() method for collections):
use Elasticms\Xliff\Facades\Xliff;
$posts = Post::where('needs_translation', true)->get();
$xliffContent = $posts->toXliff('en', 'fr'); // New fluent method
file_put_contents(storage_path('app/translations.xlf'), $xliffContent);
First Import (new updateFromXliff() for models):
$xliff = simplexml_load_file(storage_path('app/translations.xlf'));
Post::where('locale', 'en')->updateFromXliff($xliff, 'fr'); // New collection method
src/Xliff.php (new fluent methods)src/Concerns/HasXliff.php (new model traits)src/Importers/XliffImporter.php (batch processing improvements)tests/Unit/CollectionMethodsTest.php for new fluent API examples.Localize a Blog Post with Fluent API:
Post::where('locale', 'en')->get()->toXliff('en', 'es')->saveTo(storage_path('app/translations.xlf'));
$xliff = simplexml_load_file(storage_path('app/translated.xlf'));
Post::where('locale', 'en')->updateFromXliff($xliff, 'es');
New Trait: Use HasXliff for model-level methods:
// app/Models/Post.php
use Elasticms\Xliff\Concerns\HasXliff;
class Post extends Model
{
use HasXliff;
// Now supports:
$post->toXliff('en', 'fr'); // Single model export
Post::where('locale', 'en')->updateFromXliff($xliff, 'fr'); // Batch import
}
New Option: Fine-grained HTML segmentation control:
$posts->toXliff('en', 'fr', [
'segment_html' => [
'tags' => ['p', 'div', 'span'], // Only segment these tags
'max_length' => 200, // Split long segments
],
]);
New Job Class: Use ExportXliffJob with chunking:
// Export via queue with chunking
Post::where('locale', 'en')->chunk(100, function ($posts) {
ExportXliffJob::dispatch($posts, 'fr');
});
New Structure: Nested metadata support:
$posts->toXliff('en', 'ja', [
'metadata' => [
'project' => [
'name' => 'MyApp',
'version' => '1.0',
],
'translator' => 'Acme Corp',
],
]);
$this->app->singleton('xliff', function ($app) {
return new \Elasticms\Xliff\Xliff($app['config']['xliff']);
});
Blade::directive('translate', function ($expression) {
return "<?php echo app('xliff')->getTranslation({$expression}, request()->locale); ?>";
});
updateFromXliff() with pivot tables:
$translations = PostTranslation::where('locale', 'en')->get();
$translations->updateFromXliff($xliff, 'fr');
Route::get('/xliff/export', function () {
return response($posts->toXliff('en', request('target_locale')), 200)
->header('Content-Type', 'application/xml');
});
$posts = Post::factory()->count(3)->create();
$xliff = $posts->toXliff('en', 'fr');
$this->assertStringContainsString('<file', $xliff);
$xliff = simplexml_load_string(file_get_contents('tests/fixtures/translation.xlf'));
Post::where('locale', 'en')->updateFromXliff($xliff, 'fr');
$this->assertDatabaseHas('posts', ['locale' => 'fr']);
Deprecated Methods (7.3.0):
Xliff::export() and Xliff::import() are deprecated. Use fluent methods instead.// Old:
Xliff::export($posts, 'en', 'fr');
// New:
$posts->toXliff('en', 'fr');
XML Memory Limits (Worsened):
XMLWriter for large exports:
$writer = new XMLWriter();
$writer->openMemory();
$posts->toXliff('en', 'fr')->saveTo($writer);
Locale Validation (Stricter):
en_US instead of en).$locale = strtolower(str_replace('_', '-', $locale));
Batch Import Conflicts:
updateFromXliff() may overwrite existing translations silently.upsertFromXliff() for safer updates:
Post::where('locale', 'en')->upsertFromXliff($xliff, 'fr');
Special Characters (New Handling):
html_entity_decode() if needed:
$cleanValue = html_entity_decode($translation['value'], ENT_QUOTES, 'UTF-8');
validateXliff() helper:
if (!Xliff::validateXliff($xliff)) {
\Log::error('Invalid XLIFF: ' . Xliff::getValidationErrors());
}
config(['xliff.debug' => true]);
getSegments() method:
dd($post->toXliff('en', 'fr')->getSegments());
Default Settings (Updated):
New defaults in config/xliff.php:
'default_version' => '2.2',
'segment_html' => [
'enabled' => true,
'tags' => ['p', 'div', 'span', 'h1', 'h2'],
'max_length' => 150,
],
'locale_format' => 'en_US', // New strict format
'debug' => env('XLIFT_DEBUG', false), // New debug mode
Migration Guide: Run the config publisher if upgrading:
php artisan vendor:publish --provider="Elasticms\Xliff\XliffServiceProvider" --tag="config"
Then update config/xliff.php for new options.
How can I help you explore Laravel packages today?