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

Translation Yaml Tools Bundle Laravel Package

nowo-tech/translation-yaml-tools-bundle

Symfony bundle for working with YAML translation files: extract and organize translation keys, sort and merge YAML catalogs, detect missing or unused entries, and keep locale files consistent. Streamlines translation maintenance across multiple languages.

View on GitHub
Deep Wiki
Context7

Getting Started

Treat this as a dev/CI-only console tool, not a runtime bundle. Nothing here belongs in a production container.

  1. Install as a dev dependency

    composer require --dev nowo-tech/translation-yaml-tools-bundle
    

    If Flex does not auto-register it, add it to config/bundles.php guarded by environment so the commands never ship to prod:

    if (in_array($env, ['dev', 'test'], true)) {
        Nowo\TranslationYamlToolsBundle\TranslationYamlToolsBundle::class => ['all' => true],
    }
    
  2. Discover the actual surface before writing anything else. With 0 stars and 0 dependents there is no battle-tested documentation, so the source of truth is the bundle itself:

    bin/console list                     # filter for the bundle's command namespace
    bin/console help <command> --help    # options: --dry-run, --domain, --locale...
    bin/console config:dump-reference <alias>   # find the alias if it isn't obvious
    grep -r "getAlias" vendor/nowo-tech/translation-yaml-tools-bundle/src/DependencyInjection
    

    Also open src/DependencyInjection/Configuration.php — that file is the definitive list of provider keys (google, deepl, libretranslate) and their options.

  3. First use case: flatten one file, look at the diff, nest it back. Do not start with "sort my whole translations tree". Pick a single domain (messages.en.yaml), copy it aside, and run the nested↔flat conversion with whatever dry-run/diff flag the command offers. The whole point of the bundle is nested-tree ↔ flat-key conversion plus key sorting; verify the round-trip is byte-stable on your files before trusting it on the repository.

  4. Configure the minimum: provider credentials via env (GOOGLE_TRANSLATE_API_KEY, DEEPL_AUTH_KEY, etc. — confirm names against Configuration.php), and point the bundle at your translations directory. Leave machine translation off until you have sorted your existing files, because sorting and translating in the same change makes review impossible.

Implementation Patterns

Sorting as a normalised repo invariant. Run key sorting once across translations/, commit it as a single dedicated commit (chore: sort translation keys), add that SHA to .git-blame-ignore-revs, and then enforce it in CI. The CI job is the highest-value pattern here: a sort command run with --dry-run (or git diff --exit-code after running it) fails the build when someone adds an unsorted key, which kills the entire class of translation-merge conflicts. Do this before you enable anything else.

Flat-file editing for bulk work. The flattening command is most useful as an authoring aid: flatten messages.de.yaml to a key.subkey: value file, edit/hand it to a translator, nest it back, review the diff. Keep the flat intermediate out of the repository — it is a scratch artefact.

Missing-key extraction → machine translation → human review. The realistic workflow is: use the reference locale (en) as the source of truth, diff against target locales to find missing keys, send only those keys to the provider, write them into the target YAML, then treat the output as a draft. Never let MT output reach main without a reviewer, and never run the translate command over keys that already exist (most implementations overwrite).

Wire it into Composer scripts / Makefile, not into developers' muscle memory:

"scripts": {
    "translations:sort": "bin/console <sort-command>",
    "translations:check": "bin/console <sort-command> --dry-run"
}

This keeps the invocation (and the inevitable command-name churn) in one place.

Pluggable providers are the extension point. The bundle advertises Google/DeepL/LibreTranslate plus "pluggable", so the day-to-day pattern is: implement the bundle's provider interface in your app, register it as a service with the tag the bundle's compiler pass consumes (check src/DependencyInjection/*CompilerPass* for the exact tag), and select it by name in the config. This is how you route through an internal gateway, add a cache, or add a provider the bundle doesn't ship. For LibreTranslate you can self-host, which is the right pick if source strings are sensitive.

Do not run it over vendor/. Scope the command to your own translations/ tree and exclude any vendored bundles' translation directories, either via the command's path argument or an exclude pattern in config.

Gotchas and Tips

  • Adoption risk is the headline. Zero stars, zero dependents, a release date in the future relative to most ecosystems — pin the exact version in composer.json and read the command source before relying on it. Budget for the possibility that it is abandoned and you fork it.
  • Sorting rewrites entire files. Any diff-shaping tool that reorders keys will touch every line. Land the initial sort as its own commit, keep it out of feature PRs, and use .git-blame-ignore-revs — otherwise git blame on your translation files becomes useless.
  • YAML round-trips lose things. Symfony's YAML dumper will drop comments, may reflow block scalars (| / >) and multi-line strings, and can requote values. If you rely on comments or exact formatting in translation files, test the round-trip on a copy first; consider the sort command the only rewriter you allow, and never round-trip files that carry comments.
  • Key ordering is not obviously defined. Check whether sorting is byte-wise or locale-aware, and whether numeric keys, %placeholder% keys, and dots-in-keys are handled sanely. Mixed conventions (a.b.c vs literal a.b.c keys) will bite on flatten/nest.
  • Machine translation mangles placeholders. %count%, {{ name }}, :attribute, ICU {count, plural, ...} blocks, and HTML tags are routinely corrupted by every MT API. Add a post-translation validation step (placeholder parity + ICU parse check per locale) before merging, and never auto-commit MT output.
  • Never commit API keys. Pull them from env vars, and remember these are metered APIs — a naive "translate all missing keys across 15 locales" run can be expensive in one command. Start with one locale, --dry-run everything, and check for a cache/batch option in the command's --help.
  • Rate limits and partial failures. Expect 429s and mid-run failures. Run per-file/per-locale so a failure doesn't leave one file half-translated and uncommitted; always start from a clean worktree so git diff shows exactly what the tool produced.
  • Framework compatibility must be verified, not assumed. Target is PHP ≥ 8.1 with Symfony 6/7/8, but confirm with composer why-not symfony/framework-bundle on your actual version, and check src/Resources/config/services*.php for deprecated service definitions before upgrading Symfony.
  • Extension points to prefer: the translation-provider interface + tag (for custom providers), decorating the bundle's commands (cleanest way to add your project's placeholder validation or caching without forking), and the DI extension's config tree (don't hardcode paths in commands). Avoid subclassing the commands — the internals are not a stable API at this maturity level.
  • Debugging: run commands with -vvv and --dry-run first; if a command isn't listed, the bundle isn't registered in config/bundles.php for that environment — that is the single most common "it's installed but nothing happens" failure.
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.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core
nodisrupt/laravel-agent
sierratecnologia/media-manager