Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Translations Editor Laravel Package

shas/translations-editor

A web-based editor for Laravel language files. Browse translation keys across locales, edit or add strings in a clean interface, and save changes directly to your project's translation files without touching PHP arrays by hand.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Upgrade/install the package

    composer require vendor/package:^2.0
    php artisan vendor:publish --tag="package-config"
    

    v2.0.0 is a major bump, so even though the headline change is "added online translation functionality," diff the published config against your existing config/package.php before assuming a drop-in upgrade — major versions routinely rename keys, namespaces, and driver strings. Run php artisan config:clear and commit the republished config.

  2. Configure the online translation driver The new feature is almost certainly opt-in. Expect something like:

    // config/package.php
    'driver' => env('TRANSLATION_DRIVER', 'file'), // or 'online'
    'online' => [
        'provider' => env('TRANSLATION_PROVIDER', 'deepl'),
        'api_key'  => env('TRANSLATION_API_KEY'),
        'endpoint' => env('TRANSLATION_ENDPOINT'),
    ],
    

    Add the credentials to .env and to .env.example, phpunit.xml (as null/fakes), and your deployment secrets store. Never commit a real key.

  3. Look here first

    • CHANGELOG.md / UPGRADE.md for the v1 → v2 migration notes.
    • The package's published config file — it is the most accurate documentation of what the online driver supports.
    • The service provider's bindings, so you know what contract (e.g. Translator, TranslationDriver) to type-hint or fake in tests.
  4. First use case: translate a missing key on demand

    // app/Http/Controllers/DashboardController.php
    public function index(Translator $translator)
    {
        $greeting = $translator->online()->translate('Welcome back, :name', 'fr', ['name' => $user->name]);
    
        return view('dashboard', compact('greeting'));
    }
    

    Or, more likely for the file-based workflow, a console command that scans lang/en/*.php, detects keys absent from other locales, and fills them via the online provider:

    php artisan translations:sync --locale=fr --driver=online --dry-run
    

    Always run with --dry-run (or your package's equivalent) first, then review the git diff before committing machine output.

Implementation Patterns

Keep the online driver behind an abstraction. Wrap it in a small app-level service so you can swap providers, add caching, and fake it in tests:

namespace App\Services;

use Vendor\Package\Contracts\Translator;

class TranslationService
{
    public function __construct(private Translator $translator) {}

    public function translate(string $text, string $locale, array $replace = []): string
    {
        return Cache::remember(
            "tr:{$locale}:" . md5($text),
            now()->addDay(),
            fn () => $this->translator->driver('online')->translate($text, $locale, $replace)
        );
    }
}

Batch, don't loop. Online translation is an HTTP round-trip per call (or per batch). Never call it inside a Blade loop or a foreach over a collection of user content — collect the strings, dedupe them, and issue one batch request. Most providers accept arrays of up to 50–128 segments.

Queue the writes, not the reads. Syncing translations to disk/DB is slow and failure-prone; push it to a job:

class SyncLocaleTranslations implements ShouldQueue
{
    public $tries = 3;
    public $backoff = [10, 60, 300];

    public function __construct(public string $locale) {}

    public function handle(TranslationService $service): void
    {
        foreach (Lang::getMissingKeys($this->locale) as $key => $source) {
            $service->store($this->locale, $key, $service->translate($source, $this->locale));
        }
    }
}

Use it for user-generated content, not UI strings. The strongest day-to-day use case is translating dynamic content — product descriptions, support tickets, comments — where you can't hand-write translations. Keep static UI strings in lang/ files under version control and human review; machine-translated UI copy tends to be subtly wrong and hard to audit.

Locale negotiation. Online providers expect specific codes (en-US, pt-BR, zh-Hans) that often differ from Laravel's en_US / pt_BR. Add an explicit mapping table in config and normalise at the boundary, not scattered through call sites.

Fallback chain. Wire the online driver as a fallback, not the primary, so a provider outage degrades gracefully:

'fallback_chain' => ['file', 'online', 'source'],

Cache aggressively, invalidate by version. Cache keyed on locale + hash(source) + provider so a provider switch doesn't serve stale translations.

Gotchas and Tips

  • The major version bump is the real risk. "Added a feature" in a v2 usually ships alongside renamed config keys, changed method signatures, or a new required dependency. Run the full test suite and grep your codebase for the package namespace before deploying. If there's no UPGRADE.md, compare the v1 and v2 tags on the config file and service provider directly.

  • Cost and rate limits are silent until they aren't. Add a hard cap ('online.max_characters_per_day' => 100_000) and log every request. A stray translate() inside a loop over 10k rows will burn through a paid quota in one request. Handle 429 with exponential backoff — the package's built-in retry may be off by default.

  • Placeholders and HTML get mangled. :name, {count}, <strong>, and %s are frequently corrupted by machine translation. Verify the driver preserves them; if not, tokenise placeholders (__PH1__), translate, then substitute back. Test every locale with a string containing all placeholder syntaxes you use.

  • Pluralisation is not a translation problem you can outsource. Providers rarely handle Laravel's trans_choice pipe syntax ({0} none|{1} one|[2,*] many). Translate the variants individually and assemble the plural string yourself.

  • Never machine-translate into a locale you ship without review. Especially legal text, error messages, and anything with a brand name. Add a do_not_translate config list (['Acme', 'Pro Plan', 'OAuth']) and verify the provider honours it — many providers let you pass a glossary or "ignore tags".

  • Testing: fake the HTTP layer, not the package. Http::fake() on the provider endpoint keeps tests fast and offline-friendly. Also add a test asserting the container resolves the file driver when TRANSLATION_API_KEY is null, so a missing env var in CI doesn't silently turn into live API calls.

  • Config caching quirks. Because the driver is typically env-driven, a stale bootstrap/cache/config.php after a deploy will keep the old credentials or the old driver. Put php artisan config:cache in your deploy script after secrets are injected, and clear it in local dev when switching drivers.

  • Escape output, always. Machine-translated text coming back from a third party is untrusted input. Render with {{ }} / e(), never {!! !!}, unless you've explicitly sanitised the provider response.

  • Extension point to watch: if the package exposes a driver contract, implement a CachedTranslator or FallbackTranslator decorator and bind it in a service provider rather than editing vendor config. That survives the next major bump.

  • Debugging checklist when a translation comes back in the source language: (1) is the driver actually online in the cached config? (2) is the source locale correctly detected — providers will happily "translate" en → en? (3) is the cached value from an earlier failed run? (4) did the batch silently drop segments over the provider's limit? Log the raw request/response payloads at debug level for the first week after rollout.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager