dejwcake/admin-translations
A Laravel package for managing application translations from your admin panel, letting you edit and organize language strings through a database-backed interface instead of editing language files by hand.
Architecture fit. Despite the "lightweight setup" framing in the package description, this is not a dev-time utility. The package is a fork of brackets/admin-translations (namespace Brackets\AdminTranslations) that ships a service provider which replaces Laravel's translation loader with TranslationLoaderManager, merging file-based strings with database rows via array_replace_recursive — DB wins. It also brings migrations (a translations table with jsonb columns), admin routes under /admin/translations, three gates (admin.translation.index/edit/rescan), a regex source scanner (admin-translations:scan-and-save), and Excel import/export via maatwebsite/excel. The UI is explicitly built "based on Admin UI," i.e. the Craftable admin panel. If our admin surface is not Craftable, the headline feature — the UI — is unusable and we are left with the loader, scanner, and import pipeline.
Integration feasibility. Mechanically straightforward on the happy path: composer install, swap Laravel's translation service provider for this one, run migrations, register gates, mount routes. Real feasibility questions are environmental:
^8.5 and Laravel 13 (per its own contributor guide), which is ahead of most production stacks. That must be reconciled against our pinned versions before anything else.brackets/admin-translations (identical classes/services) is a hard conflict; we must ensure only one is installed.Technical risk. High relative to the package's maturity signal (0 stars, single maintainer, fork). The blast radius is production translation resolution, not a build step. Specific hazards:
trans()/__(). Every resolution path now depends on the database being reachable.saved/deleted events. Any write path that bypasses the model (seeders, raw SQL, imports in another service, direct DB edits) leaves stale strings indefinitely, with no TTL to self-heal.text/metadata are jsonb, tested on MariaDB 12.3 and PostgreSQL. MySQL 8 or SQLite behavior is unverified.Key questions.
trans() when the database is unavailable — exception, empty string, or file fallback?brackets/admin-translations — will security fixes be merged forward?assessment-pm.md states this is "tooling, not a translation platform" and a "dev-only, low-risk dependency." The contributor docs contradict that (service-provider loader swap, DB override of runtime strings). That framing must be corrected before it reaches stakeholders.Stack fit. Fit is conditional: Laravel + Craftable Admin UI + MariaDB/PostgreSQL + maatwebsite/excel. Fit drops to "partial" if we are on a different admin framework (UI benefit lost) or a Laravel/PHP version below the target matrix (blocked). The scanner alone has a much wider fit — it is a CLI command operating over lang files and source.
Migration path. Treat the runtime loader swap as a separate adoption decision from the tooling:
admin-translations:scan-and-save in CI or a sandbox, and use the output as a key-coverage audit across lang/. No service-provider swap, no production runtime change. This delivers most of the localization-roadmap value with near-zero risk.TranslationLoaderManager in staging for a single non-critical locale group, with the DB seeded from the scanner. Keep file translations intact as the fallback layer.Compatibility checks before any merge. Laravel/PHP constraint resolution; absence of upstream brackets/admin-translations; maatwebsite/excel version alignment; migration compatibility with our existing schema (new table, no collisions expected but verify); cache driver is centralized, not array/file; auth guard used by the admin routes matches our admin guard.
Sequencing. Scanner → staging loader → production one locale → gate and authorization review → expand. Do not sequence the admin UI rollout before the authorization review; editing customer-facing copy is a content-integrity change, not a code change, and needs an approval owner named up front.
Maintenance. Patch cadence looks cheap: 2.3.2 is explicitly a no-op on upgrade, and the maintainers run PHPStan, phpmd, phpcs, and a MariaDB/PostgreSQL test matrix — good hygiene signals. The offsetting cost is fork ownership: someone must track upstream brackets/admin-translations and decide whether this fork inherits its fixes. Pin the version, review lockfile diffs on every bump, and note that dist archives now exclude tests/Docker/QA config via export-ignore — a small supply-chain positive, and nothing we should be depending on.
Support. No vendor SLA. Zero stars and a single-maintainer bus factor mean the escape hatch matters more than the roadmap: because the loader swap is a single service-provider substitution, reverting to stock Laravel file-based translations is a small, reversible change. Document that rollback and rehearse it once in staging. Budget for the realistic case where we fork internally.
Scaling. Admin write volume is trivially low. The scaling concern is read-path: translation resolution moving from in-memory/file to database-backed. The permanent cache is the mitigation, but it turns the cache into a hard correctness dependency — cold cache after a deploy means a burst of queries, and coarse invalidation means one key edit flushes more than necessary. Plan a cache-warm step on deploy and confirm the cache store is shared across all nodes and workers.
Failure modes.
| Failure | Impact | Mitigation |
|---|---|---|
| Database unreachable | trans() resolution errors — potentially every page |
Confirm/implement file fallback; test explicitly |
| Write bypasses Eloquent | Stale strings forever, no TTL to recover | Route all writes through the model; ban direct DB edits |
| Blank/wrong DB row | Silently masks correct file copy | Preview-before-publish; diff view in review workflow |
| Import of malformed Excel | Overwrites or deletes keys | Require backup export before import; transactional review |
| Scanner transaction failure | Soft-deleted translations left unresolved | Keep transactional; run in off-hours; verify restore path |
| Gate misconfiguration | Non-admins can edit customer-facing copy | Map gates to existing roles; audit before enabling UI |
| Multi-node cache divergence | Users see different copy by node | Shared cache store; verify invalidation fan-out |
| Unsupported stack after upgrade | Blocks Laravel/PHP upgrades | Pin and validate against our upgrade calendar |
Ramp-up. Engineering ramp-up is small — a few days for install, migration, and the staging swap. The real ramp-up is organizational: someone must own localization governance (who may edit, what review is required, how exports are versioned). Without that owner, the admin UI becomes an unlogged back door into customer-facing copy. Recommend a scoped pilot — inventory plus one locale group — and a documented decision on whether a TMS (Crowdin/Lokalise/Phrase) is the longer-term home, with this package as the cheap interim inventory and editing layer rather than the destination.
How can I help you explore Laravel packages today?