jeffersongoncalves/laravel-translation-manager
A Laravel package that provides a web interface for managing application translations. Browse, add, and edit translation keys across locales, helping you maintain language files without manually editing PHP arrays.
Install the package with Composer, then complete the two-step database setup that is now required as of 1.1.0:
composer require <vendor>/translation-manager
php artisan vendor:publish --tag="translation-manager-migrations"
php artisan vendor:publish --tag="translation-manager-config" # if you have not already
php artisan migrate
The migration is no longer loaded from the package. Since 1.1.0 it ships as a publishable stub named create_translation_lines_table, declared in the service provider via hasMigrations(). If you skip the publish step on a fresh install, you get the package's code but no translation_lines table.
Where to look first, in this order:
database/migrations/*_create_translation_lines_table.php. Read the columns before writing any application code; this is the shape of your translation store and the thing you are most likely to want to extend.hasMigrations() is registered and note the publish tag (translation-manager-migrations) and any config/route/view tags it exposes alongside.First use case, end to end: publish the migration and config, migrate, then insert one line per locale for a single key, read it back through whatever lookup the package provides, and confirm the rendered output changes when you edit the row. Doing that loop once on a scratch install surfaces caching and fallback-locale behaviour before it surprises you in a real project.
Make the publish step part of deployment, not documentation. Fresh environments (CI, a new staging box, a teammate's clone) will fail without the migration. Put the publish and migrate in your deploy script or a small setup command so the stub is guaranteed to exist:
php artisan vendor:publish --tag="translation-manager-migrations" --force
php artisan migrate --force
Use --force deliberately here: on a fresh container the file does not exist yet, and on repeat deploys re-writing an unmodified stub is harmless because the migration is idempotent. If you have customised the stub locally, drop --force so you never clobber your edits.
Treat the published migration as the extension point. The main practical benefit of the 1.1.0 change is that the migration is now yours to edit before it runs. Add columns (a namespace, an is_reviewed flag, an author id), tune the unique index on the locale/key pair, or change the column types to match an existing translations table. Do this before the first migrate on a new install. Doing it afterwards means writing a separate follow-up migration — which is the correct move once the table exists anywhere shared.
Database as source of truth, files as the transport. The common working pattern is: seed translation_lines from existing lang/ files on install, let editors work in the package's UI or API against the table, then export back to PHP/JSON files at build time for the runtime to consume. Keep the export step in CI or a release command so the table and the files cannot drift unnoticed.
Scope lines by group and locale from day one. Even a small app accumulates keys fast. Use whatever grouping the package supports (typically a group/namespace column) rather than one flat namespace, so you can export, cache, or purge a single feature area without a full-table operation.
Wrap reads in a cache layer keyed by locale. Translation lookups happen on nearly every request; reading a row per key is the classic mistake. Cache the resolved map per locale and bust it when a line is saved — usually by having the save path forget the relevant cache key rather than rebuilding the whole map.
Multi-tenant and test setups. For tests, run migrate:fresh (which now depends on the published stub existing in database/migrations) and seed only the lines under test. For tenant-scoped apps, confirm whether the package's lookup is global; if it is, either add a tenant column to the stub or namespace your keys, otherwise tenants will read each other's copy.
Upgrading from 1.0 requires no action. The old package-loaded migration and the new stub produce the same table. Running the publish step on an existing 1.0 install is safe because the stub skips creation when the table already exists — useful when standardising every environment on the same setup command.
Class "create_translation_lines_table" not found / missing-table errors on fresh installs. The migration is no longer auto-loaded, so any existing setup script, Dockerfile, or onboarding README written for 1.0 is now incomplete. Audit every place you provision the app.SHOW CREATE TABLE translation_lines against the stub after upgrading; if they differ, write a normal migration.vendor:publish --force overwrites silently. If you customised the stub, --force in a deploy script will revert your columns on the file, even though the database is untouched — a nasty inconsistency to debug later. Either keep the stub pristine and extend via follow-up migrations, or omit --force.translation-manager-migrations, plural and package-prefixed. A wrong tag prints "no publishable resources" and exits successfully — the migration then fails much later with a confusing error. Run php artisan vendor:publish with no arguments to list available tags if unsure.php artisan config:clear (and view:clear if the package ships views). Stale cached config is the usual cause of "I changed the setting and nothing happened".migrate:rollback on the idempotent stub should drop the table only if it created it. Verify this on a scratch database before relying on it in a pipeline; a rollback that drops a table you seeded by hand is a bad afternoon.How can I help you explore Laravel packages today?