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

Locale Bundle Laravel Package

ticketpark/locale-bundle

A Symfony bundle for managing application locales, tying request locale detection, routing, and translation together so your app can serve the right language to each user with minimal configuration.

View on GitHub
Deep Wiki
Context7

Getting Started

Before you install anything: this bundle is archived and its last release was July 2017. Treat it as a legacy-maintenance dependency only. If you are starting a new project, the same problem is solved today by Symfony's TranslatableMessage, Doctrine's json column type plus a small value object, or a dedicated translation-storage bundle. Only reach for ticketpark/locale-bundle if you inherited a codebase that already depends on it and you need to keep it working.

Install and register (legacy Symfony 2.x/3.x style):

composer require ticketpark/locale-bundle
// app/AppKernel.php
$bundles = [
    // ...
    new Ticketpark\LocaleBundle\TicketparkLocaleBundle(),
];

There is no Flex recipe and no autoconfiguration for a bundle of this vintage, so on any modern Symfony (4+) you will either need to register it manually in config/bundles.php or accept that it will not boot cleanly. Check composer.json of the bundle for the exact symfony/* and php constraints before committing.

Where to look first, in this order:

  1. Model/ (or Entity/) — find the class that actually holds the translations. This is almost always an array/map of locale => string wrapped in a value object with getters such as getTranslation($locale) and a fallback mechanism. Everything else in the bundle orbits this class.
  2. Doctrine/ or Types/ — the bundle ships a custom Doctrine type (typically named something like localized_string) that serializes the value object into a TEXT/JSON column. Confirm the exact registered type name in the bundle's extension class or Resources/config/services.yml.
  3. Twig/ — the Twig extension is your day-to-day interface. Look for the filter/function name so you can render a localized field in templates without unwrapping the object by hand.
  4. Tests/ — with a 0-star, archived package the test suite is the only reliable documentation. Read the fixtures to see the real expected storage format.

First use case: add a localized name to an existing entity. Declare the column with the bundle's Doctrine type, persist a translation map, then render the current-locale value in a Twig template. Once that round-trips correctly, you understand 80% of the package.

Implementation Patterns

Map the column through the custom Doctrine type. The intended pattern is to let Doctrine own the serialization rather than storing an array by hand:

/**
 * @ORM\Column(type="localized_string", nullable=true)
 */
protected $name;

Persisting then becomes $product->setName(new LocalizedString(['en' => 'Shirt', 'de' => 'Hemd'])). Verify the type name against the bundle's service definition — it is not guaranteed to be localized_string.

Always read through the value object, never the raw column. Access the property via getTranslation($locale) (or whatever the accessor is called) so the bundle's fallback logic applies. If you bypass it and pull the array out of the column directly you lose fallback-to-default-locale behaviour and will render blank strings for untranslated locales.

Integrate with the request locale once, at the boundary. Resolve the locale in a kernel/request listener or from $request->getLocale(), and pass it explicitly into the value object or the Twig filter. Avoid having the bundle reach into the container for the locale from inside the model — it makes the value objects untestable and behaves badly in console commands and queue workers where there is no request.

Form handling. If the bundle ships a form type for the localized field, expect a compound or collection-style widget keyed by locale rather than a single text input. If it does not, bind a CollectionType keyed by a locale array and hydrate the value object in the form's onSubmit/data transformer. The latter is usually cleaner than depending on an unmaintained form type.

Twig rendering. Prefer a single Twig filter for output so escaping and fallback stay centralised:

{{ product.name|localized_string(app.request.locale) }}

Wrap that in one template partial for entities with several localized fields, so the locale argument is passed in one place rather than repeated across templates.

Seed and migrate in the same shape the type expects. In fixtures and migrations, write the serialized structure the Doctrine type produces (array → JSON/text). If you insert a plain PHP array via raw SQL the type will not be able to hydrate it on read; keep all writes going through the ORM, or replicate the exact serialization.

Workflow that fits this bundle: editorial translations are authored in an admin form per locale, stored in the localized column, and read back with request locale at render time. There is no extraction/import step and no integration with Symfony's translation catalogue — this bundle stores per-record localized strings, not messages.en.yaml. Keep those two systems clearly separated in your head; they solve different problems.

Gotchas and Tips

  • Archived and unsupported. No security fixes, no Symfony 4+/PHP 7.2+ compatibility. Pin your platform versions in composer.json before touching anything, and expect Composer to refuse the install on a modern stack.
  • Doctrine schema diff will fight you. Custom DBAL types over TEXT/JSON frequently cause spurious doctrine:schema:validate / migrations:diff churn. Confirm the type's getSQLDeclaration and requiresSQLCommentHint settings; if the type does not return true from requiresSQLCommentHint, Doctrine may drop and recreate the column on every diff. You can work around it by adding a column comment or by overriding the type registration.
  • Missing vs empty translation. A null entry and a missing key often behave differently in the fallback path (and false/0 values can be swallowed by loose null checks). Normalise on write: decide whether an untranslated locale is null or simply absent, and be consistent.
  • Fallback chains are usually one-level. Most bundles of this era fall back from de_AT to a configured default locale, not through de_AT → de → en. If you need a full chain, implement it in a decorator around the value object rather than patching the bundle.
  • Escaping is your responsibility. A localized string is user/editor content; render it with Twig autoescaping. If the bundle's Twig extension returns Twig_Markup or similar marked-safe output, pass plain strings through it, never HTML from untrusted editors.
  • Serialization hazards. If the type stores JSON, malformed or legacy data (e.g. PHP-serialized arrays from an earlier version) will throw on hydration and take down an entire listing page. Add a defensive read path or a one-off migration to normalise stored values.
  • Caching pitfalls. If you cache rendered pages or fragments, the cache key must include the locale. A localized value object is locale-agnostic at the storage layer, which makes it easy to accidentally cache the en rendering and serve it to de visitors.
  • Console and messenger context. There is no request locale in CLI. Set the locale explicitly on the value object or a translator/locale service before rendering anything in a command, worker, or email builder.
  • Extension points to prefer over forking: the Doctrine type (swap serialization format), the Twig extension (change rendering/fallback), and the value object itself if the bundle's model is not final. If you must patch internals, fork the package into src/ or use a Composer replace with a vcs repository entry — never edit vendor/.
  • Debugging tip: dump the raw column first, then the hydrated value object. The failure is almost always at the serialization boundary, not in the fallback logic, and separating those two steps saves a lot of time.
  • Migration plan. If you are on this bundle today, isolate every use behind a small interface (getTranslation(string $locale): ?string) in your own codebase. That gives you a one-file swap to Symfony's TranslatableMessage or a JSON column when you finally remove the dependency.
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.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core