PHPLaravelPackage
View on GitHub github.com/paper-leaf-tech/laravel-translation

Introducing laravel-translation

Keeping track of translations or strings in general are a recurring source of friction. Developers don't want to play copy editor, and translators don't want to touch PHP arrays. laravel-translation moves the source of truth to a Google Sheet and keeps your Laravel files in lock-step via a push/pull workflow. The Google Sheet becomes a version controlled source of truth, which can be populated from the codebase and then easily pulled back in when content is accurate.

What it does

  • 🔄 Bi-directional sync — push translations to Google Sheets and pull updates back.
  • ✏️ Surgical pull — updates land in place via AST manipulation; comments, blank lines, indentation, and quote styles are preserved.
  • 🌍 Multi-language by defaulttranslations:push with no argument syncs every locale under lang/.
  • 🔤 Translator-friendly sheets — non-English sheets show the English source alongside each translation.
  • 🔐 Service Account authentication — simple, secure auth using a Google service account.
  • 🗂️ Local JSON backups — sheet snapshots written to a gitignored folder before every push.

Why AST instead of regeneration

The original version of this package regenerated translation files from scratch on every pull. That worked, but it nuked comments, blank lines, and any custom formatting. Switching to AST manipulation (via nikic/php-parser) means pull only touches the string values whose keys already exist in your file — nothing else moves.

Sheet layout

Each locale gets its own tab named Translations - {locale}:

  • Source locale (en): Column A is the key, B is the original value, C is the editor's revised wording.
  • Other locales (fr, es, …): Column A is the key, B is the English source, C is the translation. Rows with an empty C are skipped on pull, falling through to Laravel's fallback_locale.

Installation

The package lives at paper-leaf-tech/laravel-translation.

"repositories": [
    {
        "type": "github",
        "url": "[email protected]:paper-leaf-tech/laravel-translation.git"
    }
]
composer require paper-leaf-tech/laravel-translation --dev
php artisan vendor:publish --tag=laravel-translation-config

The workflow

  1. Initial pushphp artisan translations:push from a project with lang/en/ (and optionally other locales). Each locale gets its own tab.
  2. Translators work in the sheet — non-source tabs show English in Column B and let translators fill Column C.
  3. Pullphp artisan translations:pull writes Column C back to the matching lang/{locale}/*.php files. Untranslated rows are left alone.
  4. Re-push when you add new keys to your code.

Guardrails on pull

Pull intentionally won't create files, append new keys, or touch non-string values. Anything unexpected gets surfaced as a warning rather than silently rewriting your code:

⚠ Skipped 1 new key(s) in lang/en/auth.php (add to code first, then re-pull):
    - auth.captcha.invalid