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

Craftable Translatable Laravel Package

dejwcake/craftable-translatable

Adds multilingual, translatable field support to the Craftable Laravel admin panel, letting you manage content in multiple languages with locale tabs and translation-aware form fields. Simple to install and configure for building multilingual admin interfaces.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. The package follows idiomatic Laravel extension patterns: a HasTranslations trait on Eloquent models, a Translatable service for locale resolution, and a TranslatableFormRequest that bridges translatable attributes into Laravel's validator. This is a low-coupling design — it composes with the framework rather than replacing it, so it slots into an existing Laravel codebase without imposing a new persistence or validation paradigm. For teams already storing per-locale content in JSON or side tables, the fit is high; for teams using a dedicated translation package or a CMS-managed i18n layer, this is duplicative.

Integration feasibility. High. 2.0.1 is a maintenance release with an explicit "nothing to do when upgrading" statement, no schema changes, no config changes, and no deprecations. Adoption effort is a composer update plus a regression run. The changes are internal hardening: closure parameter types, a defensive is_array() guard before array_search() in rules(), and container-based app resolution in getLocale().

Technical risk. Low, with two narrow caveats worth verifying rather than assuming:

  • Adding parameter types to closures inside HasTranslations::toArray(), Translatable::getLocales(), and TranslatableFormRequest is invisible to normal consumers, but any code that overrides these methods or subclasses the form request and re-declares the closures could hit a signature mismatch or a stricter type error under strict_types.
  • The is_array($rule) guard fixes a real defect: string rules (e.g. 'required|string|max:255') were previously passed into array_search() and would emit warnings or behave unpredictably. The fix changes runtime behavior for affected call sites — a correctness improvement, but validation output or error message shape may shift for teams that unknowingly depended on the buggy path.
  • getLocale() resolving via the container instead of the app() helper is a testability and Octane-safety improvement; confirm it behaves identically in console commands and queued jobs where the container is present but the request lifecycle differs.

Key questions.

  1. What are the supported PHP and Laravel version ranges for the 2.x line, and does our oldest supported app fall inside them?
  2. Does any of our code subclass TranslatableFormRequest or override toArray() / getLocales() / getLocale()? (Determines whether the typing changes are truly a no-op for us.)
  3. What changed in 2.0.0? The notes cover only the patch; we need the 2.0.0 breaking-change list before pinning ^2.0.
  4. Are there consumer-visible changes to validation error messages from the rules() fix, and do we have tests asserting on those messages?
  5. What is the CI status and test coverage for this release, and is the maintainer response time acceptable for a dependency on our critical path?

Integration Approach

Stack fit. Assumes a Laravel application on PHP 8.x with Eloquent models that hold translatable attributes. The package is additive: trait on the model, optional form request base class for validation, no migrations or service providers to wire beyond standard package discovery. Teams not using Form Requests get value from the model trait alone, so partial adoption is viable.

Migration path. Straightforward, staged:

  1. Pin ^2.0 in composer.json and upgrade in a branch; run the full test suite plus any locale-specific feature tests.
  2. Grep for overrides of toArray(), getLocale(), getLocales(), and subclasses of TranslatableFormRequest; inspect each for closure-signature compatibility.
  3. Grep form request rules() for string-form rules on translatable fields — this is the exact surface the guard touches — and confirm validation still passes and messages are unchanged.
  4. Smoke-test locale resolution in a queued job and an artisan command, not just an HTTP request, to validate the container-resolution change.
  5. Roll out behind the normal release train; no data migration or dual-write period required.

Compatibility. No breaking changes declared in 2.0.1. The upgrade is patch-level in semver terms, so a lockfile bump is sufficient once step 2 and 3 above are cleared. The one non-obvious incompatibility class is subclass overrides, which semver does not protect.

Sequencing. Do the 2.0.0 breaking-change review first (it gates the whole ^2.0 line), then this patch, then the validation-path audit, then queue/console smoke tests. If we are already on 2.0.0, steps 1–3 collapse into a single afternoon of work.

Operational Impact

Maintenance. Minimal. The package is small, has no runtime infrastructure footprint, and this release adds no configuration surface. Ongoing cost is essentially dependency-bump hygiene plus periodic review of upstream releases. The visible CI investment — matrix across PostgreSQL and MariaDB, healthchecked docker-compose — is a positive signal that the maintainer is testing against realistic database backends rather than SQLite only, which matters if we rely on JSON column querying or collation-sensitive translation lookups.

Support. Single-maintainer risk is the primary concern for any package of this shape; the assessment should record maintainer responsiveness and release cadence as tracked metrics rather than assume them. Patch releases with clear "nothing to do when upgrading" notes are a good sign of disciplined release management. Our mitigation is a thin wrapper layer around the trait's public methods so that a fork or replacement is a contained change.

Scaling. No runtime scaling concerns — the trait resolves locales in-process and does not add queries beyond what the model already issues, provided we eager-load or constrain translation relations ourselves. Watch for N+1 patterns when rendering many translated models in a list view, and for JSON-column translation storage on very large tables where locale-filtered queries may not use indexes effectively on either PostgreSQL or MariaDB.

Failure modes.

  • Silent locale fallback: getLocale() returning an unexpected locale in a job or console context could produce content in the wrong language without erroring. Detect via assertions in queue/console tests.
  • Validation drift: the rules() guard changes the code path for string rules; a mis-handled array/string boundary could make a translatable field fail validation in one locale only. Detect via per-locale form request tests.
  • Override breakage at upgrade time: subclassed closures failing on typed parameters — a hard error at request time, caught by test coverage if the form requests are exercised.
  • Locale data integrity: translation rows or JSON keys missing for a locale, surfacing as empty strings rather than exceptions. Detect via a data-quality check or model-level test fixtures.

Ramp-up. Low. A Laravel-proficient engineer can be productive with the trait in under an hour and with the form request integration in half a day. The main onboarding item is documenting our internal convention for where translations live, how fallback is configured, and which locales the app must support — the package's README covers the API but not our operational rules, so that belongs in our own docs.

Recommendation. Adopt/upgrade to 2.0.1. Effort is small and the release is a net correctness improvement, particularly the rules() guard. Gate the upgrade on the two verification tasks above (subclass/override audit, string-rule validation audit) and on reviewing the 2.0.0 changelog if we have not already moved to the 2.x line.

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.
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
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