Download the PHP package tonydev/lara-glot without Composer
On this page you can find all versions of the php package tonydev/lara-glot. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download tonydev/lara-glot
More information about tonydev/lara-glot
Files in tonydev/lara-glot
Package lara-glot
Short Description Auto-translation for Laravel models, language files, and Filament. Drivers for Anthropic Claude, OpenAI, DeepL, Google, and Ollama, with glossary locking and aggressive caching.
License MIT
Informations about the package lara-glot
LaraGlot
Automatic translation for Laravel. LaraGlot translates Eloquent models with JSON translatable attributes, nested page-builder content, and static PHP language files — and it goes to great lengths to never pay for the same translation twice.
Five drivers ship out of the box: Anthropic Claude, OpenAI, DeepL, Google Translate, and Ollama for local models. Laravel placeholders, URLs, HTML tags, and your brand terms survive translation intact.
Table of Contents
- Requirements
- Installation
- Configuration
- Drivers
- Keeping Costs Down
- Glossary and Brand Terms
- Quality Review Pass
- Placeholder Protection
- Model Setup
- Language File Translation
- Artisan Commands
- Queue Setup
- Filament Integration
- Custom Drivers
- Custom Prompts
- Failure Behaviour
- Upgrading to 2.1
- Upgrading from 1.x
- License
Requirements
| Requirement | Version |
|---|---|
| PHP | ^8.3 |
| Laravel | ^11.0 \| ^12.0 \| ^13.0 |
| spatie/laravel-translatable | ^6.0 (for model translation) |
| filament/filament | ^4.0 \| ^5.0 (for the admin UI) |
Installation
The service provider is auto-discovered. Then publish the config:
Two drivers need an extra package; the rest use Laravel's HTTP client directly:
If you use queued model translation, make sure job batching is migrated:
Running php artisan migrate also creates the lara_glot_translation_retries table, which tracks values that fell back to source text so laraglot:retry can re-attempt them. It's optional — without it, translation still works and LaraGlot logs a single notice instead of tracking fallbacks.
Configuration
Pick a driver and set its key in .env:
Every driver accepts the same tuning knobs in config/lara-glot.php: chunk size, retries, retry delay, concurrency, HTTP timeout, and cache TTL. The defaults are sensible; you rarely need to touch them.
For slow reasoning models (e.g. DeepSeek-class models behind an OpenAI-compatible endpoint), raise the timeout and/or lower the chunk size:
When a chunk still times out (or gets rate-limited), the LLM drivers automatically retry it in smaller sub-chunks before falling back, so one slow request no longer drops a whole chunk of strings to source text.
Fallback detection
When a driver fails on a string, that string falls back to the source text. LaraGlot refuses to let that go unnoticed:
laraglot:files --syncprints a per-filetranslated / identical-to-sourcecount, warns when the fallback share exceedslara-glot.fallback.warn_ratio(default0.5), and exits non-zero on failures.- When every translatable string in a file comes back identical to the source — the signature of a failed run — the file is not written and the job fails so it can retry, instead of an untranslated English file masquerading as done. Disable via
LARAGLOT_FAIL_ON_FULL_FALLBACK=falseif a locale is legitimately identical to the source.
Protected values
Values that are references rather than prose — 'link' => 'route:contact', bare URLs, mailto:/tel: links — are passed through untranslated. Patterns are configurable in lara-glot.protected_value_patterns.
Drivers
| Driver | Needs a key | Best for |
|---|---|---|
anthropic |
yes | Best translation quality. Defaults to claude-haiku-4-5 (fast, cheap); set claude-sonnet-5 when nuance matters most. |
openai |
yes | Works with any OpenAI-compatible endpoint — OpenAI, Azure, Groq, Together AI. Defaults to gpt-5-mini. |
deepl |
yes | Strong European-language quality at a flat per-character price. Free-tier keys (ending :fx) are detected automatically. |
google |
no | Prototyping and low-volume work. Uses the unofficial web endpoint — no SLA, so don't build production on it. Long strings are split on sentence boundaries automatically (LARAGLOT_GOOGLE_MAX_LENGTH, default 1500 chars) since the free endpoint 500s on long payloads, and every response is verified to have preserved placeholder tokens before being accepted. |
ollama |
no | Fully local and free. Point it at any model your hardware can run. Defaults to llama3.2. |
To use another OpenAI-compatible provider, change the base URL — no code changes:
Keeping Costs Down
This is where LaraGlot earns its keep. A translation API call is made only when a string has genuinely never been translated before:
- In-process cache. Within one request or job, a repeated string costs a RAM lookup, nothing more.
- Persistent cache. Every translation is stored in your Laravel cache (30 days by default), keyed per string, per language pair, per driver. Re-running a command, re-saving a model, or rebuilding language files re-uses everything already translated.
- In-batch deduplication. If "Save" appears forty times across your language files, it is sent to the API once and fanned back out to all forty keys.
- Change detection. Model translation tracks a hash of the source content and skips fields that haven't changed since the last run.
- Per-string caching, not per-chunk. Editing one string in a file invalidates that string only — the other forty-nine stay cached.
In practice a second full run over an unchanged project costs zero API calls. You can verify this yourself: every driver exposes getStats() with cache hits, misses, and the actual API call count.
Glossary and Brand Terms
Two tools to keep terminology under control:
protected_terms are shielded with the same token mechanism used for URLs, so even Google and DeepL can't mangle them. Matching is case-sensitive and whole-word: LaraGlot is protected, laraglots is not.
Changing the glossary automatically invalidates the affected cached translations — you never serve stale wording after a terminology decision.
Quality Review Pass
Machine translation is accurate but often stiff. With the review pass enabled, each freshly translated chunk gets a second call where the model acts as a native-speaker reviewer: it fixes overly literal phrasing, replaces vocabulary no real product would use, and returns already-good translations unchanged.
Cost notes, because they matter:
- The review only runs on strings that weren't cached — and the reviewed result is what gets cached. You pay the extra call once per string, ever.
- If the review call fails for any reason, the first draft is kept. A translation is never lost to the reviewer.
- LLM drivers only; Google and DeepL ignore the flag.
Placeholder Protection
Translation engines will happily turn :count into :nombre and break your app. Before any text leaves your server, LaraGlot replaces sensitive tokens with opaque markers, and swaps them back afterwards:
Input:
Sent to the API:
After restore:
This is a hard guarantee enforced in code, not a prompt instruction, and it applies to every driver and every translation path.
Model Setup
Add the trait to any model using spatie/laravel-translatable:
Register it in config/lara-glot.php:
Nested JSON content (page-builder sections, repeaters) is translated recursively. Keys listed in ignored_keys — identifiers, security values, media paths, locale/format config, geo and ordering fields, timestamps — are passed through untouched. The published config ships with a comprehensive list of keys that are never human-readable labels (id, uuid, slug, sku, token, avatar, latitude, created_at, …); add your own app-specific keys there. Deliberately absent are words like email or price that are often translatable labels in language files.
Language File Translation
Translates your lang/en/*.php files into every configured locale, preserving nested key structure:
Files listed in exclude_files (framework files like validation) are skipped.
Artisan Commands
laraglot:sync
Scans registered models and dispatches translation jobs for anything new or changed.
laraglot:files
Translates PHP language files. See the section above for options (file?, --locale=, --force, --sync).
laraglot:audit
Reports every language-file key and model attribute whose value is byte-identical to the source locale — the signature of a silent translation fallback — and can repair them in place:
- Exits non-zero when any file/model locale is flagged at or above the threshold, so it works as a CI gate or scheduled canary (
Schedule::command('laraglot:audit')). --repairre-translates only the values still equal to the source (missing keys included) with a forced cache refresh, so fixing fallbacks never re-bills the whole corpus and evicts poisoned cache entries.- Values that are supposed to be identical across locales belong in
lara-glot.audit.allowlist— they're never flagged or re-billed. The default list ships with common acronyms, units, and platform names ("OK", "SMS", "PDF", "iOS", "PayPal", …); extend it in the published config.ignored_keysandprotected_value_patternsare excluded automatically.
laraglot:retry
Whenever a value falls back to source text during a translation run, LaraGlot records it in the lara_glot_translation_retries table — a fallback is never silent. This command re-attempts those units:
- Bounded, with back-off: each failed attempt reschedules the unit at
base_delay_minutes × 2^attempts(default 30 min base); aftermax_attempts(default 5) the unit is parked as exhausted and the command exits non-zero so it surfaces for human review instead of re-billing forever. Tune vialara-glot.retry. - Never wastes an API call: units whose source text changed, whose key was removed, or that were already healed elsewhere (an audit
--repair, a--forcerun, a manual edit) are resolved without touching the driver. - Idempotent + resumable: run it on a schedule (
Schedule::command('laraglot:retry')->hourly()) and coverage converges; exhausted strings that are legitimately identical belong inlara-glot.audit.allowlist.
Queue Setup
Heavy work runs on Laravel queues (translations by default):
For production, run the worker under Supervisor with --timeout above the model job timeout (600s).
Filament Integration
Register the plugin in your panel provider:
You get a management page showing translation coverage per model and language, with actions to queue missing or forced re-translations.
Custom Drivers
Register your own engine without forking the package. In a service provider's boot():
Then set LARAGLOT_DRIVER=my-engine. The driver needs to implement Tonydev\LaraGlot\Contracts\TranslationDriverInterface — two methods, translate() and translateBatch(). Extend AbstractLlmDriver instead if your engine is prompt-based and you want chunking, caching, deduplication, glossary support, and the review pass for free; then the only method to write is sendChunk().
Custom Prompts
The built-in LLM prompt asks for translations that read like a native speaker wrote them, matching the register of the source text. If you want full control:
The string replaces the built-in prompt entirely; {source} and {target} are substituted. Changing it invalidates the affected cache entries, same as glossary changes.
Failure Behaviour
Two rules, depending on where you are:
At render time (a page reading a translation), failure is graceful: a failed translation returns the original string, never an exception and never half-translated token soup. Placeholders are restored even on the fallback path — users never see __VAR_0__.
In jobs and commands, failure is loud — a batch that writes English into lang/ar/ while reporting success is corruption, not resilience:
- Chunks retry with exponential back-off; transient failures (timeouts, 429s, 5xx) additionally retry in halved sub-chunks before any string falls back.
- A batch driver error throws — the job fails visibly and retries, and nothing gets cached or written.
- A file whose output is 100% identical to the source is treated as a failed run: not written, job failed.
- Any individual string that does fall back is recorded in the retry table and re-attempted by
laraglot:retry— a fallback is acceptable, a silent fallback is not. - Corrupt cache entries read as misses and are evicted automatically; forced refreshes (
--force,--repair, retries) bypass every cache layer, including the driver's own. - Everything is logged under the
[LaraGlot:Driver]tag.
Upgrading to 2.1
2.1 fixes a data-corrupting bug and tightens failure behaviour. Read this if you ran 2.0 in production:
- Critical fix — multibyte corruption: under Laravel's default
processconcurrency driver, translations to Arabic, Chinese, Hindi, and other multibyte scripts were silently replaced with the English source (unserialize(): Error at offset …in the log was the only trace). Fixed for both file and model translation. Audit your existing locales —php artisan laraglot:auditreports the damage and--repairheals only the affected values. - Filament v4/v5 only: the admin page uses the Schemas API and a non-static
$view; Filament 3 panels are no longer supported. - Run
php artisan migrate: creates the optionallara_glot_translation_retriestable used bylaraglot:retry. - Behaviour change: batch translation failures in jobs/commands now throw instead of silently writing source text; a 100% source-identical file fails the job instead of being written. Escape hatch:
LARAGLOT_FAIL_ON_FULL_FALLBACK=false. ignored_keysdefaults grew substantially (identifiers, media paths, timestamps, …). If any of the new defaults collide with translatable label keys in your app, remove them in your published config.- New config blocks —
retry,audit(threshold + allowlist),fallback,protected_value_patterns, per-drivertimeout,drivers.google.max_length— all optional with sensible defaults; re-publish the config to pick them up.
Upgrading from 1.x
ignored_keysdefaults shrank to a generic list. If you relied on removed defaults (cta_url,is_active, and similar app-specific keys), add them to your published config.- Ollama caching changed from chunk-level to string-level. Old chunk cache entries are simply ignored; strings re-cache individually on the next run.
- New config blocks (
glossary,review,prompt,drivers.anthropic) are optional — re-publish the config or copy them in if you want the new features. - Model defaults moved to current generations (
gpt-5-mini,llama3.2). Pin your previous model via env if you need to stay put.
License
MIT. Created by TONY THE DEVELOPER
All versions of lara-glot with dependencies
illuminate/bus Version ^11.0|^12.0|^13.0
illuminate/cache Version ^11.0|^12.0|^13.0
illuminate/concurrency Version ^11.0|^12.0|^13.0
illuminate/console Version ^11.0|^12.0|^13.0
illuminate/database Version ^11.0|^12.0|^13.0
illuminate/filesystem Version ^11.0|^12.0|^13.0
illuminate/http Version ^11.0|^12.0|^13.0
illuminate/queue Version ^11.0|^12.0|^13.0
illuminate/support Version ^11.0|^12.0|^13.0