tomatophp/tomato-translations
Tomato Translations is a Laravel package for managing app translations from an admin interface. Browse, add, and edit language files and database-backed strings across locales without touching code, making multilingual Laravel apps simpler to maintain.
What it is, in one line: a DB-backed translation key store + Filament admin UI + Google Translate integration, with an Artisan command (added in v1.2.6) that machine-translates a scoped path instead of the whole app.
Minimum steps to a running loop:
Pin and install.
composer require tomatophp/tomato-translations:^1.2.6
Pin the version — this thing moves in patch releases and you want a known commit behind your translation files.
Read the source before you trust it. The docs are thin (one-line release notes). Before wiring anything up, open the package's src/ and answer three things for yourself:
php artisan list | grep -i translat after install).lang/ files, the DB, or both.Everything else in this assessment is downstream of those three answers.
Publish config + run migrations.
php artisan vendor:publish --tag=tomato-translations
php artisan migrate
Migrations stand up the key store. Confirm your existing lang/ files import without loss before you let anything write back to disk.
Register the admin surface. This is Filament/TomatoPHP-native — you add the package's resource/plugin to a panel provider. Do it on a non-production, non-default panel first so it doesn't silently expose translation editing to every admin.
Credentials in .env. A dedicated Google Cloud Translate API key, not a shared one, with quotas and a budget alarm set. Treat every string the command sees as data leaving your infrastructure.
First use case — the safe one: pick one low-risk locale (say es), one bounded path (a single module or a resources/views subtree — not app/), run the command, and diff the output. Treat generated strings as drafts that need review, not as shippable copy.
Where to look first in the repo: the command class, the config file (route/middleware/Google settings), and the migration that defines the key table. That's ~80% of the package's behavior.
Pattern 1 — DB as editor surface, files as source of truth.
The cleanest mental model: lang/ files in VCS remain authoritative; the package is a producer/editor in front of them. The web UI edits the DB key store, then you export back to files (or let the package do it — verify which). This keeps rollback trivial (git checkout lang/) and stops the DB from becoming a shadow translation system that drifts from disk.
Pattern 2 — Per-sprint, path-scoped translation. The v1.2.6 command is the reason this package is interesting. Wire it into a workflow like:
feature branch → new strings in module X → artisan translate --path=Modules/X --locale=es
→ review diff → commit as drafts → human pass → ship
This is the difference between "one big localization project" and "localize incrementally." It's also the only way this package earns its keep in a release runbook.
Pattern 3 — Non-engineer editing loop. Product/copy folks edit in the Filament UI within their locale; engineers review the resulting file diff. This works only if you've made the DB→file direction explicit and deterministic. If the package writes to disk directly on UI save, agree on who has write authority to that directory before anyone touches it.
Pattern 4 — Guard the human-curated keys.
Keep a small, explicit set of "reviewed" translation keys (brand names, legal copy, marketing strings) and make sure the command's behavior protects them. If it overwrites, maintain those keys in a separate file/namespace the command never reaches, or gate the command behind --force semantics you control.
Pattern 5 — Machine translation as a draft pipeline, not a shipping pipeline. Run the command, commit the output to a branch, open a PR, review the diff. The diff is your review artifact. This is how you get the speed benefit without shipping unreviewed machine output to customers.
Integration tips:
lang/ itself. Blast radius stays small.The big one — unknown write semantics. The release note is a single line and a link to one commit. Assume nothing about overwrite vs. merge vs. skip. This is the risk that decides the whole evaluation: an auto-translate command that clobbers reviewed copy is destructive and hard to notice until it's shipped. Test on a scratch branch with git clean before you ever run it against real copy.
"Path" is undefined in the docs. It could mean a directory (recursive?), a glob, or a translation namespace. Verify before you scope it to a module — a wrong guess could mean translating the entire app/ tree when you wanted one folder.
No documented dry-run. Until you confirm otherwise, treat the command as having side effects the moment you run it. Wrap it: run on a throwaway branch, or copy lang/ somewhere first.
Idempotency is unproven. Re-running a machine-translation command can churn output (different strings each run, unstable ordering), which turns your review diff into noise and quietly defeats the human-review gate. Test re-run behavior explicitly.
Provider failure is non-deterministic. Google Translate can rate-limit, quota-cap, or fail mid-run — which raises the question of whether a partial failure leaves files half-written. Don't put this in CI until you know the failure behavior; if you do, make it non-blocking and artifact-only.
Costs and data egress. Per-character billing plus the reality that every string the command touches leaves your network. If any of those strings are internal, customer PII, or legally sensitive, that's a governance decision, not a technical one — and it's the thing most likely to kill adoption at review time.
Concentration risk, priced in. Two stars, zero dependents, single maintainer, last release April 2024. This package is fine as an internal admin convenience; it is not a release-blocking dependency. Assume bug fixes are yours to write or fork.
Version drift. 2024-era package, unspecified Laravel/PHP support ranges. Validate on a scratch app matching your production Laravel major + PHP version before touching the real repo. Filament version alignment is the other likely snag.
DB ↔ file drift. If the DB key store and the on-disk lang/ files can diverge, they will. Pick a direction (DB→file, always) and enforce it, or you'll spend a sprint reconciling "which copy is real."
Extension points to reach for first:
The go/no-go checklist (do this in a one-sprint spike): exact command signature and exit codes; overwrite/merge/skip behavior; dry-run and diff artifacts; path resolution semantics; API failure and partial-write behavior; idempotency on re-run; Laravel/PHP/Filament compatibility; and the DB key store's migration/rollback story. If you can't answer all of these from source and a spike, don't wire it into a release workflow.
How can I help you explore Laravel packages today?