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

Translatable Laravel Package

savannabits/translatable

A Laravel package for translating Eloquent model attributes across multiple locales, letting you store and retrieve localized values with locale fallbacks. Useful for multilingual apps that need simple, flexible model translations without heavy dependencies.

View on GitHub
Deep Wiki
Context7

Getting Started

This is the first standalone release of the Translatable package, versioned in lockstep with savannabits/craftable: ^7.0.0. Treat it as the translatable-model layer of the Craftable admin ecosystem rather than a general-purpose i18n library.

Minimal setup:

  1. Verify your stack matches Craftable 7. Since this release pins to ^7.0.0 of the Craftable meta-package, confirm your Laravel/PHP versions satisfy Craftable 7 requirements before installing in isolation. Installing this package outside a Craftable 7 project is untested territory.
  2. Install and publish. composer require savannabits/translatable (or as pulled in transitively by savannabits/craftable), then check for publishable config/migrations with php artisan vendor:publish. Start by reading the package's config/ and any migration stubs — that tells you whether translations live in JSON columns or a side table.
  3. Look here first: the HasTranslations-style trait (in src/), the service provider bindings, and the default/fallback locale config. Those three determine 90% of day-to-day behavior.
  4. First use case: make one existing model translatable, add a locale switcher to a form, and confirm reads/writes round-trip in two locales — including the fallback path when a translation is missing.

Because there is no prior assessment and the release note is a single line, validate assumptions against the actual source rather than assuming Laravel-Translatable parity.

Implementation Patterns

Trait-based model translation. The expected pattern is use HasTranslations on an Eloquent model, declaring a $translatable array of attributes. Store/retrieve via the model as normal; the trait intercepts attribute access per active locale.

Locale resolution. Drive the active locale from App::getLocale() and set it in middleware from the request (session, user preference, or route segment). Keep a separate fallback locale for reads so admin UIs never show blanks.

Form handling. In Craftable admin forms, render one input group per configured locale, keyed by locale code, and map them back to the translatable attribute array on save. Validate each locale's required fields explicitly rather than relying on the model.

Ecosystem integration. Since this ships as part of the Craftable 7 bundle, prefer registering it through the Craftable service provider flow and reusing Craftable's locale configuration instead of maintaining a second locale list. If you run Craftable's generators, confirm generated CRUD includes translated fields — if not, extend the stubs.

Version alignment. Pin savannabits/translatable and savannabits/craftable to the same major (^7.0.0). Treat a bump on one without the other as unsupported.

Gotchas and Tips

  • Sparse release notes = read the changelog in git. A "first release" line tells you nothing about breaking surface. Diff v7.0.0 against the pre-split implementation (or the upstream the trait was extracted from) before upgrading a production app.
  • Fallback vs. null semantics. Be explicit about whether a missing translation returns the fallback locale or null. This is the single most common source of "empty field" bugs; assert it in a test early.
  • JSON storage and querying. If translations are stored in JSON columns, where('name', ...) will not match translated values on all DB drivers. Use the package's query scopes/helpers, or add generated columns, rather than raw where on translated attributes.
  • Mass assignment and dirty tracking. Translated attributes often bypass normal $fillable/isDirty expectations. Verify save() persists all locales and that getDirty() reflects changes per locale.
  • Serialization. Check what toArray()/API resources emit — full locale map or active locale only. Configure explicitly; don't inherit accidental behavior into a public API.
  • Middleware ordering. If locale comes from auth/user settings, the locale-setting middleware must run after auth and session middleware.
  • Extension points. Prefer overriding the locale resolver and fallback config over forking the trait; the package is version-locked to Craftable, so local forks will fight future updates.
  • Debugging tip. When a translation "disappears," check in order: active locale, fallback config, whether the attribute is actually listed in $translatable, then the raw DB value — in that order, it resolves most issues fastest.
  • Caveat on this assessment. With only a one-line release note and no source inspection, the specifics above are the conventional shape for this class of package. Confirm trait name, config keys, and storage strategy against src/ and config/ before relying on them.
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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin