atico/spreadsheet-translator-symfony-bundle
Install Core Package:
composer require samuelvi/spreadsheet-translator-symfony-bundle
Add Required Adapters (pick one provider, reader, and exporter):
composer require samuelvi/spreadsheet-translator-provider-localfile
composer require samuelvi/spreadsheet-translator-reader-matrix
composer require samuelvi/spreadsheet-translator-exporter-xliff
Configure (config/packages/atico_spreadsheet_translator.yaml):
atico_spreadsheet_translator:
frontend:
provider:
name: 'local_file'
source_resource: '%kernel.project_dir%/var/translations.xlsx'
exporter:
format: 'xliff'
prefix: 'app_'
domain: 'messages'
destination_folder: '%kernel.project_dir%/translations'
shared:
default_locale: 'en'
name_separator: '.'
lazy_mode: true
First Use Case:
Create a spreadsheet with columns: section, subsection, en_US, es_ES, etc.
Run the command to generate translations:
php bin/console atico:spreadsheet-translator:export
Spreadsheet as Single Source of Truth:
google_drive or one_drive providers for cloud collaboration.provider:
name: 'google_drive'
source_resource: 'https://docs.google.com/spreadsheets/d/SPREADSHEET_ID/edit'
Automated CI/CD Pipeline:
git push to main branch.CronBundle or a GitHub Action to run:
php bin/console atico:spreadsheet-translator:export --env=prod
Multi-Domain Support:
auth, admin).domain in config or use a custom command with --domain:
php bin/console atico:spreadsheet-translator:export --domain=admin
Lazy Mode for Efficiency:
lazy_mode: true to auto-generate hierarchical keys (e.g., contact.form.email).Locale-Specific Overrides:
default_locale to fall back to English if translations are missing.es_MX, pt_BR) for regional variants.| Command | Purpose |
|---|---|
php bin/console atico:spreadsheet-translator:export |
Export all configured spreadsheets. |
php bin/console atico:spreadsheet-translator:export --domain=auth |
Export only the auth domain. |
php bin/console atico:spreadsheet-translator:export --dry-run |
Validate spreadsheet structure without writing files. |
php bin/console atico:spreadsheet-translator:export --force |
Overwrite existing translation files. |
Service Autowiring: Inject the translator service into controllers/services:
use Atico\Bundle\SpreadsheetTranslatorBundle\Service\SpreadsheetTranslator;
public function __construct(private SpreadsheetTranslator $translator) {}
Event Listeners:
Listen for kernel.terminate to auto-export translations on request:
public function onKernelTerminate(RequestEvent $event): void {
$this->translator->export();
}
Twig Integration: Use Symfony’s built-in translation system with the generated files:
{{ 'homepage.title'|trans }}
Locale Format Mismatch:
en_US, es_ES format (not en, es).intl extension to validate locales:
\IntlDateFormatter::create('en_US', IntlDateFormatter::NONE);
File Permissions:
destination_folder) must be writable by the web server.chmod -R 775 %kernel.project_dir%/translations
Google/OneDrive Auth Issues:
google_drive_auth/one_drive_auth, ensure OAuth credentials are configured in services.yaml:
services:
Atico\Bundle\SpreadsheetTranslatorBundle\Provider\GoogleDriveAuthProvider:
arguments:
$clientId: '%env(GOOGLE_CLIENT_ID)%'
$clientSecret: '%env(GOOGLE_CLIENT_SECRET)%'
Empty or Malformed Spreadsheets:
section/subsection columns will break key generation.--dry-run to validate before export.Lazy Mode Quirks:
contact.form → contact.form.email).Enable Verbose Output:
php bin/console atico:spreadsheet-translator:export -v
Check Logs:
framework:
profiler: { only_exceptions: false }
Validate Spreadsheet Structure:
matrix reader’s debug mode (if available) or inspect the raw data:
$reader = new \Atico\SpreadsheetTranslator\Reader\MatrixReader($spreadsheet);
var_dump($reader->getData());
Custom Providers:
\Atico\SpreadsheetTranslator\Provider\AbstractProvider to support AWS S3, Dropbox, etc.class S3Provider extends AbstractProvider {
public function getSpreadsheet(): \PhpOffice\PhpSpreadsheet\Spreadsheet {
$client = new \Aws\S3\S3Client([...]);
$file = $client->getObject([...]);
return $this->reader->loadFromStream($file['Body']);
}
}
Custom Exporters:
\Atico\SpreadsheetTranslator\Exporter\ExporterInterface for JSON, CSV, or database exports.class JsonExporter implements ExporterInterface {
public function export(array $data, string $locale, string $domain): string {
return json_encode($data, JSON_PRETTY_PRINT);
}
}
Pre/Post-Export Hooks:
# config/services.yaml
services:
App\EventListener\TranslationExportListener:
tags:
- { name: kernel.event_listener, event: atico.spreadsheet_translator.export, method: onExport }
Cache Exports:
$cache = new \Symfony\Component\Cache\SimpleFileCache($this->cacheDir);
if (!$cache->get('translations_exported_at')) {
$this->translator->export();
$cache->set('translations_exported_at', true, 3600);
}
Batch Processing:
$spreadsheet = $provider->getSpreadsheet();
foreach ($spreadsheet->getSheetNames() as $sheetName) {
$worksheet = $spreadsheet->getSheetByName($sheetName);
$this->processWorksheet($worksheet);
}
Disable Lazy Mode for Large Projects:
lazy_mode: false and manually define keys.How can I help you explore Laravel packages today?