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

Entity Translations Bundle Laravel Package

vm5/entity-translations-bundle

A Symfony bundle for adding locale-aware translations to Doctrine entities. Store and retrieve translated fields per language, manage multilingual database content, and integrate translations into forms and templates with minimal configuration. Ideal for multilingual Symfony applications.

View on GitHub
Deep Wiki
Context7

Getting Started

This package is a Symfony bundle, not a Laravel package — no service provider, no config/entity-translations.php, no Eloquent integration. Before writing any code, decide which side you're on:

  • Symfony 4/5 app (the intended target): composer require vm5/entity-translations-bundle, register Vm5\EntityTranslationsBundle\EntityTranslationsBundle in config/bundles.php, and enable the Doctrine metadata listener. Read tests/Fixtures in the repo first — the fixtures are the clearest documentation for how a translatable entity is wired.
  • Laravel app (the likely case for you): don't install it. Use astrotomic/laravel-translatable for the closest conceptual match (separate *Translation table, locale-aware fallback, per-model translation class) or spatie/laravel-translatable if you want a JSON column and simpler setup.

The first use case the bundle demonstrates — and the one worth stealing conceptually — is translating a small set of fields (title, description) on an entity into N locales with a fallback to the app default, driven by an injected Translator service rather than by manually fetching a Translation row.

Implementation Patterns

  • Core pattern: a parent entity marked translatable + a sibling *Translation entity holding localized fields + a Doctrine association between them. The bundle's metadata listener attaches the association and a translator service hydrates the right translation row based on the active locale.

  • Laravel equivalent:

    // Article.php
    use Astrotomic\Translatable\Translatable;
    use Astrotomic\Translatable\Contracts\Translatable as TranslatableContract;
    
    class Article extends Model implements TranslatableContract {
        use Translatable;
        public $translatedAttributes = ['title', 'body'];
    }
    
    // ArticleTranslation.php
    class ArticleTranslation extends Model {
        public $timestamps = false;
        protected $fillable = ['title', 'body'];
    }
    
  • POPO support is the differentiator. The bundle's pitch is that it can translate plain old PHP objects, not just Doctrine entities. There is no Laravel equivalent out of the box; you'd write a small TranslatesObjects trait or a TranslationBag value object yourself. Worth reading the bundle's POPO code path if you build this — it's a clean separation of "source value" vs "localized value."

  • Schema: keep translations in a separate table with a composite unique index on (translatable_id, locale). That's the schema the bundle generates and the one astrotomic expects too. It's more queryable than a JSON column and lets you WHERE translations.title LIKE ? in joins.

  • Locale detection: Symfony's LocaleListener derives locale from _locale/Accept-Language. Laravel analog: a SetLocale middleware calling App::setLocale($request->getPreferredLanguage(config('app.locales'))).

  • Persisting translations: in the Doctrine pattern you persist translation entities explicitly (cascade or manual collection update). In astrotomic, $translatedAttributes are saved via the parent. If you port any code between the two, this asymmetry is the first thing that will bite you.

Gotchas and Tips

  • Framework mismatch is the headline. A Symfony DI-wired, Doctrine-event-driven bundle cannot be dropped into Laravel. You are evaluating a pattern and reference implementation, not a dependency.
  • Maintenance risk is high. Last release 2021-01-22, 9 stars, 0 dependents, annotation-based (@Translatable) rather than PHP 8 attributes. doctrine/annotations is deprecated in favor of attributes — this bundle will not survive that transition cleanly. Do not depend on it for a new project.
  • Fallback locale is the top source of "why is my field empty" bugs. Check the configured fallback before assuming the translation row is missing; a misconfigured fallback silently returns the default locale's value for every request.
  • Translation saving is explicit, not magic. If you assume editing $article->title persists a translation automatically, you'll lose data. The parent/translation split requires deliberate save() on the translation side (or cascade config).
  • Extension point worth copying: the separate *Translation entity pattern (index-friendly, join-queryable) vs. the JSON-column pattern (spatie, simpler but weak for filtering/sorting on translated values). If you need to sort by translated titles or search them, pick the separate-table approach regardless of framework.
  • Debugging tip: because the locale is resolved by a listener, dump $translator->getLocale() (Symfony) or App::getLocale() (Laravel) at the point of failure before touching translation data — a locale that's silently en in a de request explains the majority of "translation not applied" tickets.
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.
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels