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

Translation Form Bundle Laravel Package

toovalu-github/translation-form-bundle

translation-form-bundle is a Symfony bundle for building translation-aware forms, offering reusable form types and configuration to manage localized content in one place. It simplifies adding multilingual fields to your forms without custom glue code.

View on GitHub
Deep Wiki
Context7

Getting Started

First, the framing: toovalu-github/translation-form-bundle is a Symfony bundle built on the Symfony Form component. It will not run inside a Laravel app — there is no service provider, and it depends on symfony/form, symfony/options-resolver and Twig form themes. If you're evaluating it from a Laravel codebase, treat it as a reference implementation for the "one sub-form per locale, rendered as tabs" pattern rather than a dependency you can composer require.

For a Symfony project:

  1. composer require toovalu-github/translation-form-bundle (check composer.json for the Symfony version constraint before committing — see Gotchas).
  2. Register the bundle in config/bundles.php (Toovalu\TranslationFormBundle\TranslationFormBundle::class => ['all' => true]); Flex may not auto-register it since it's a low-traffic package.
  3. Configure the locales you support — the bundle needs to know which locale set to render. Look for the extension config under translation_form: in the README, and confirm the exact key names in src/DependencyInjection/Configuration.php, which is the authoritative source when docs are thin.
  4. Where to look first: src/Form/Type/ for the exposed form types and their configureOptions(), then tests/ — for a package with 0 stars, the test fixtures are usually better documentation than the README.

First use case: a Product entity with a ProductTranslation child entity (one row per locale). You have a ProductTranslationType for a single translation and want an admin form with a tab per locale instead of hand-rolling a CollectionType keyed by locale index. That is exactly the gap this bundle fills.

Implementation Patterns

Tabbed locale editor. Wrap the translation collection in the bundle's type and pass the per-locale child form type as an option. Each tab renders your normal ProductTranslationType — so your field definitions and constraints stay in one place and remain reusable outside the admin.

Always define a dedicated translation form type. Do not reuse the parent entity's type for the translation child; translated and untranslated fields diverge quickly (slug generation, meta fields), and mixing them makes the tabbed layout confusing.

Admin integration. In EasyAdmin, register it as a custom form type on the field; in Sonata, as a custom form type in configureFormFields. Because it is a Form type and not a field type, expect to do a little wiring in the admin layer rather than getting it for free.

Controller/entity wiring. The parent must own the collection with cascade: ['persist', 'remove'] and orphanRemoval: true on the Doctrine side, otherwise submitting the form saves nothing. Handle the form normally — $form->handleRequest($request), isValid(), flush() — the bundle only touches the form layer.

Locale fallback and required locales. Model "this locale is mandatory, that one is optional" as validation groups on the translation entity's constraints, not via required => true on the widget. Empty optional translations should be allowed to exist as blank rows or be pruned on preFlush; pick one and be consistent.

Non-HTML consumers. For an API, skip the form type entirely — but you can still reuse the bundle's locale list by injecting the same configuration parameter, so the UI and API agree on what "supported locales" means.

Gotchas and Tips

  • Data mapping is index-sensitive. The collection keys must line up with the locale codes the bundle generates. If you pass ['en', 'fr'] but the entity's translations are keyed 0, 1, 2, submitted data silently lands on the wrong row. Use CollectionType by_reference => false and an index-by-locale entry_options, or verify the bundle already does this in its type.
  • Empty translation rows. Every save on a multi-locale form can create a row for every locale, including ones the editor never touched. Prune in a preFlush listener or accept the noise deliberately.
  • Cascade is on you. The most common "it doesn't save" bug is a missing cascade: ['persist'] on the inverse side of the association — the form binds fine and Doctrine drops the children.
  • Version pinning. This is a 0-star, low-traffic package. Read composer.json for the symfony/form constraint and pin it; if you're on a newer Symfony LTS than the constraint allows, vendor the form type into your app rather than fighting the resolver.
  • Extension points. The useful hooks are almost always in configureOptions() — locale list, child form type, whether to render tabs or an accordion, and required-locale options. Read that method before forking anything.
  • Debugging. When a tab renders but doesn't persist, dump($form->get('translations')->getData()) after submit() but before isValid() — you'll immediately see whether the failure is in the form mapping or in Doctrine.
  • Don't trust the release date or the star count as a quality signal either way. Read the tests; for a bundle this small, the whole surface area is a handful of classes and can be audited in twenty minutes.
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.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo