Weave 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

Jms Translation Bundle Fork Laravel Package

fchris82/jms-translation-bundle-fork

A fork of the JMS Translation Bundle for Symfony, offering tools to extract, manage, and update translation messages. It integrates with Symfony’s translation workflow to help keep locale files organized and up to date.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a fork of the original JMSTranslationBundle (JMS\TranslationBundle namespace). It provides three things: extractors that scan your PHP/Twig sources for translation calls, a web UI for editing translation files side by side, and console commands to extract and audit keys. It does not replace Symfony's runtime translator — it's a workflow tool around your existing messages.* files.

Minimal setup:

composer require --dev fchris82/jms-translation-bundle-fork

Register the bundle (JMSTranslationBundle in AppKernel/bundles.php), then add a config block. One named config per project or per bundle is the normal pattern:

# config.yml
jms_translation:
    configs:
        app:
            dirs: ["%kernel.root_dir%/../src", "%kernel.root_dir%/../templates"]
            ignored_dirs: ["%kernel.root_dir%/../vendor", "%kernel.root_dir%/../var"]
            output_dir: "%kernel.root_dir%/../translations"
            enabled_extractors: [php, twig]
            output_format: xliff

Expose the editor UI under a protected prefix and add a firewall rule:

# routing.yml
jms_translation:
    resource: "@JMSTranslationBundle/Resources/config/routing.xml"
    prefix: /_trans
# security.yml
access_control:
    - { path: ^/_trans, roles: ROLE_TRANSLATOR }

First use case: on a legacy app, point dirs at your source tree and run a dry run to see everything the extractors find before touching files:

bin/console translation:extract en --config=app --dry-run
bin/console translation:extract en --config=app        # writes skeletons

Then open /_trans, filter to untranslated messages, and edit inline. Saving writes directly back to the files in output_dir.

Implementation Patterns

Extract → review diff → commit. Treat extraction output as generated code. Run translation:extract locally after adding trans() calls, review the diff (new keys, removed keys), and commit it with the feature. In CI, run with --dry-run and fail the build if the output would change — that keeps the translation files in sync with the code without relying on developers to remember.

One config per bundle/output directory. output_dir is per-config, so if you keep Resources/translations inside bundles, define a config for each and loop in a script:

for c in app admin_bundle api_bundle; do
  bin/console translation:extract en --config=$c --no-backup
done

Curate extraction with annotations. For PHP, the extractors only pick up literal keys. Use @Ignore on methods/classes with dynamic keys, and @Desc/@Meaning to carry context into the generated file (the UI shows it to translators). This is how you keep translation:find-unused output actionable:

/** @JMS\TranslationBundle\Annotation\Ignore */
public function labelFor($type) { return $this->translator->trans('type.'.$type); }

Custom extractors for non-PHP/Twig sources. If you have JS or other files with keys, implement the bundle's ExtractorInterface (or a file extractor) and register it as a service tagged jms_translation.extractor. This is the main extension point for wiring pre-existing key catalogs into the same UI/diff workflow.

Web UI as the translator handoff. The practical workflow is: developer extracts and commits the English source strings, translator opens /_trans on staging, filters "untranslated", edits, saves. Because saving writes files, run it against a checkout where the translator's changes can be committed (or use the remote storage option to keep them in a DB and out of git).

Remote storage. The config supports a remote_storage block (e.g. MySQL) so edits go to a table rather than the filesystem. Useful in teams where translation files shouldn't be hand-edited, but it requires provisioning the table and is an extra moving part — most small teams should stick to file-backed output.

Runtime is unchanged. The bundle doesn't need to be enabled in prod for translation lookup; Symfony's normal translator reads the files you generated. You generally only need the bundle (and its routes) in dev/staging.

Gotchas and Tips

  • Dynamic keys are invisible. trans($var), concatenated keys ('foo.'.$bar), and keys built in loops are never extracted. Annotate them with @Ignore and maintain them by hand, or find-unused will keep flagging them as dead.
  • Domain must be a literal. Only trans('key', [], 'domain') with a string literal domain is attributed correctly; variable domains fall into the default domain and produce misleading output.
  • XLIFF churn. Rewrites reorder entries and reserialise attributes, so diffs get noisy even for one changed string. Keep extraction commits isolated from feature commits, or reviewers will miss real changes. --no-backup avoids .bak files littering the tree; add *.bak to .gitignore if you don't use it.
  • Secure /_trans aggressively. The UI writes to disk, and it writes wherever output_dir and dirs point. Never expose it publicly, and keep dirs narrow — pointing at vendor/ makes extraction slow and pollutes output with third-party keys.
  • Locale bootstrap. The UI lists locales based on files present in output_dir. A brand-new locale needs an initial extract (translation:extract fr --config=app) or an empty file before it appears.
  • Clear the translation cache in prod after any file change; dev usually picks up changes without a clear, which can hide the problem until deploy.
  • translation:find-unused is a hint, not a verdict. Dynamic keys, keys used only in YAML/DB-driven content, and keys consumed by external systems show up as unused. Expect false positives.
  • Concurrent edits conflict. Two people saving in the UI, or a translator saving while a developer extracts, produce merge pain. Coordinate: extract first, then hand off.
  • Fork/version risk. Last release is 2018 and the package targets the Symfony 3.x/4.0 era (ContainerAwareCommand, %kernel.root_dir%). Pin the version in composer.json, check constraints against your Symfony/PHP version before adopting, and treat it as unmaintained — don't build long-term process around it without a migration path to Symfony's own debug:translation/lint:xliff tooling or a maintained extraction tool.
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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager