pirasterize/sonata-form-builder
Sonata Form Builder adds a flexible form-building layer to Sonata Admin, letting you define, customize, and render dynamic forms with reusable fields and admin-friendly management. Ideal for projects that need configurable forms without rebuilding them in code.
composer require pirasterize/sonata-form-builder
Register the bundle alongside Sonata Admin (order matters — this bundle assumes SonataAdminBundle is already registered):
// config/bundles.php
return [
// ...
Sonata\AdminBundle\SonataAdminBundle::class => ['all' => true],
Pirasterize\SonataFormBuilder\SonataFormBuilderBundle::class => ['all' => true],
];
If the bundle ships entities (Form / Field / Submission — check src/Entity/ in the vendor dir), import its Doctrine mapping or run the migration it provides:
php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrate
Then look in vendor/pirasterize/sonata-form-builder/src/Admin/ — that is where the Admin classes live that register the drag-and-drop screens into your Sonata dashboard. Add them to sonata_admin.yaml:
sonata_admin:
dashboard:
groups:
forms:
label: Forms
items:
- pirasterize.admin.form
First use case: log into /admin, click Forms → Add new, drag fields from the palette into the canvas, save, and render the resulting form in a Twig template (see patterns below). Treat the drag-and-drop UI as the "designer" and your own controller as the "runtime" — the bundle stores the schema, you decide how to display and process it.
Schema-as-data. The core value is that a form definition is persisted (typically as JSON columns or a FormField entity relation) and rendered dynamically. Keep your application decoupled from that storage: read the definition via the bundle's admin/repository, convert it into a Symfony\Component\Form\FormBuilderInterface, and let Symfony handle validation and submission. This keeps the builder as a content tool and your app as the source of truth.
Custom field types. Extend the palette by registering additional field types. Look for the bundle's field-type registry (a service tagged or configured with an array of choice/text/textarea keys). Add your own:
services:
app.form_builder.field_type.currency:
class: App\FormBuilder\CurrencyFieldType
tags: ['sonata_form_builder.field_type']
If no tag exists, override the bundle config via a compiler pass or a prependExtension in your kernel — verify in DependencyInjection/ what the bundle actually reads.
Rendering in the frontend. Create a controller that loads the stored definition and builds the Symfony form on the fly:
public function show(string $slug, FormFactoryInterface $ff): Response
{
$definition = $this->forms->findBySlug($slug); // your repository
$builder = $ff->createBuilder(FormType::class);
$this->schemaToBuilder->apply($definition, $builder); // your adapter
$form = $builder->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// persist submission, dispatch an event...
}
return $this->render('form/show.html.twig', ['form' => $form->createView()]);
}
Submissions workflow. Wire a FormSubmittedEvent (your own) or a Doctrine listener on the submission entity to trigger notifications, webhooks, or CRM sync — do not put business logic into the bundle's admin. The admin should stay a pure UI for design.
Versioning definitions. Because the schema is mutable data, capture a snapshot on each save (e.g., append version + JSON blob to a FormRevision table). Submissions should reference the version they were rendered against, otherwise changing a field label or removing a field will silently misalign historic data.
Admin customisation. Subclass the bundle's FormAdmin to add extra actions (duplicate, preview, export as JSON, publish/unpublish):
final class CustomFormAdmin extends FormAdmin
{
protected function configureRoutes(RouteCollection $collection): void
{
parent::configureRoutes($collection);
$collection->add('duplicate', $this->getRouterIdParameter().'/duplicate');
}
}
Then register your subclass as the sonata.admin service with the same code the bundle uses so it replaces the built-in one.
composer why-not pirasterize/sonata-form-builder symfony/framework-bundle and check composer.json for symfony/* constraints. If you must go newer, budget time for a fork/patch.assets:install) and included via sonata_admin.yaml's assets config or an extra block. If the palette renders unstyled or the drag handles do nothing, it is almost always a missing assets:install or a Sonata theme mismatch — check the browser console for a 404 on the bundle's JS.createView() output will drift unless you explicitly style each field type. Use a single Twig form theme shared between the bundle's preview template and your app to keep them aligned.prePersist/preUpdate listener that rejects nameless fields and ensures unique machine names — otherwise you will get FormBuilder exceptions at runtime, not design time.php bin/console debug:container sonata_form_builder and debug:router | grep form to confirm what the bundle actually registers — with a low-activity package the README often lags behind reality.templates/ in vendor) via templates/bundles/SonataFormBuilderBundle/... over editing vendor files; similarly override Admin classes rather than patching them, so upgrades (should any arrive) are painless.How can I help you explore Laravel packages today?