ibexa/jms-translation-bundle
JMSTranslationBundle for Symfony provides a web interface for viewing and editing application translations, extracts translation keys from templates and source code, and helps keep message catalogs organized and consistent across locales.
What this actually is. Despite the README's "Symfony2" tagline, ibexa/jms-translation-bundle is a vendor fork of the long-standing schmittjoh/JMSTranslationBundle, now published under the Ibexa namespace. It is not a translation runtime library — it is a developer-time toolchain layered on top of the Symfony Translation component. Core capabilities: static extraction of translatable strings from Twig templates, PHP, form types, and validation constraints; a CLI (translation:extract) that merges extracted keys into message catalogues; XLIFF dump/update round-tripping; and an optional legacy web UI for browsing and editing translations.
Architecture fit. Good only if you are on Symfony (or, more likely, Ibexa DXP / eZ Platform, where it is effectively first-party infrastructure). It hooks into the DI container as a bundle, registers console commands, a Twig extension (desc, transchoice helpers), and file visitors backed by nikic/php-parser for AST-based extraction. If your stack is Laravel/Symfony-free, this is a hard no — there is no framework-agnostic entry point.
Integration feasibility. Straightforward for the CLI path: composer require --dev, enable the bundle, run extraction against a bundle or directory, commit the resulting XLIFF/YAML. The web UI is the risky half — it mounts routes and an editing surface, requires additional configuration, and has a history of config-related issues (see 1.0.0 changelog: "Invalid WebUI configurations", "Problem with WebUi").
Technical risk.
schmittjoh project stagnated for years; the Ibexa fork carries the modernisation work (Symfony 5 / Twig 3 / PHP 8 in 1.5.x–1.6.x). Roadmap is therefore tied to Ibexa's needs, not the general community.repeated labels, translation_domain, invalid_message).Key questions for the team. Which Symfony/PHP/Twig constraint range does the target branch declare, and does it match our runtime? Do we need the WebUI, or is translation:extract sufficient? Which catalogue format is our source of truth (XLIFF vs YAML vs ICU, added in 1.6.0)? What is our policy on enabling a translation-editing UI — dev-only, or authenticated and audit-logged? What is the fallback if Ibexa stops publishing this fork — vendoring, or migrating to symfony/translation extraction via PhpStan/php-translation/extractor?
Stack fit. Use it if you are on Symfony 5/6/7 or Ibexa DXP and want automated extraction plus XLIFF round-tripping. Skip it if your translation workflow already centres on a TMS (Crowdin, Lokalise, Phrase) with its own extraction, or if you are not on Symfony.
Migration path.
require-dev) — the extraction command and file visitors have no production runtime role.config/bundles.php (Symfony Flex) guarded to dev/test environments.config/packages/jms_translation.yaml; pin the format explicitly rather than relying on defaults.translation:extract in dry-run mode first, diff the output, then enable the update path with the "keep old translations" option so hand-edited strings are not overwritten.Compatibility checklist. Confirm the bundle's declared constraints against your pinned Symfony minor, Twig major, and nikic/php-parser version — the changelog shows repeated breakage from php-parser drift (issue #50, #514) and Symfony API removals (MessageCatalogue::all() in #8, ContainerAwareCommand removal in 1.5.0). Treat the composer constraint file as the authoritative compatibility statement, not the README.
Sequencing. Extraction CLI first (low blast radius, immediate value) → catalogue format decision → CI check that extraction produces no unexpected diff (this catches "developer added a string but forgot to commit the key") → WebUI last, or never.
Maintenance. Low ongoing cost if used purely as a dev-time CLI. The bundle itself is a small, stable dependency; the real maintenance burden is governance of the translation catalogues it generates. Because the package is a vendor fork, upgrade cadence follows Ibexa releases — expect infrequent, occasionally breaking bumps rather than continuous maintenance. Assign a named owner for the catalogue files; unowned extraction output degrades into duplicate keys and stale entries fast.
Support. No meaningful public community around the ibexa/ namespace artifact — the historical Gitter channel and issue tracker belong to the upstream project. Effectively community-of-one support: read the Resources/doc bundle docs, read the source, or raise with Ibexa if you are a DXP customer. Do not plan on rapid upstream fixes for edge-case extraction misses.
Scaling. Non-issue at runtime — nothing here sits on the request path except the optional Twig extension. Extraction runtime scales with codebase size (AST parsing of every PHP/Twig file); on a large monolith this becomes a multi-minute command, which is fine in CI and annoying locally. Catalogue file size is the practical scaling limit: very large XLIFF files produce noisy diffs and merge conflicts — partially mitigated by the sha1-based entry IDs added in 1.0.0.
Failure modes to plan for.
unlink()/simplexml_load_file() errors, fixed in 1.5.3).Ramp-up. Half a day for a Symfony developer to get the extract command productive; one to two days to wire it into CI with a diff gate and agree a catalogue format. The WebUI and advanced features (domain management, external resource loading, ICU dumping) are where documentation is thin and empirical testing is required. Recommended adoption profile: adopt narrowly as a dev dependency, avoid the WebUI unless there is a specific translator-workflow requirement, and record an exit criterion (e.g. "if the fork goes 18 months without a release compatible with our Symfony version, migrate extraction to php-translation/extractor").
How can I help you explore Laravel packages today?