enhavo/form-bundle
A subtree split of Enhavo, an open source PHP CMS built on the fullstack Symfony framework, offering a flexible system for complex data structures with a clean, usable interface. See the main repository for full documentation and details.
enhavo/form-bundle is not a standalone form library — it is a read-only subtree split of the main enhavo/enhavo CMS. That means:
enhavo/form-bundle in isolation. You require enhavo/enhavo (or the relevant Enhavo meta-package) and let it pull the form bundle in. Installing the split alone is only reasonable if you already have the Enhavo core/resource/admin bundles wired up.src/Resources/config/, and the bundle's own PHP source.Minimal path to first use:
composer require enhavo/enhavo (or the specific Enhavo packages you need) in a Symfony application.config/bundles.php:
Enhavo\Bundle\FormBundle\EnhavoFormBundle::class => ['all' => true],
# config/routes/enhavo_form.yaml
enhavo_form:
resource: '@EnhavoFormBundle/Resources/config/routing.yaml'
Resources/config/doctrine/ exists and is loaded).bin/console doctrine:schema:update --dump-sql (or generate a migration) before touching anything at runtime.bin/console cache:clear.Where to look first, in order:
src/EnhavoFormBundle.php — bundle registration and any compiler passes.src/Resources/config/ — service definitions, form type registrations, routing. This is the de-facto API surface.src/Form/Type/ and any FormType/FormField classes — the core abstraction for renderable forms.src/Entity/ (or Model/) — the persisted form/submission model.src/Resources/views/ — Twig templates you will override.First realistic use case: define a form (fields, labels, validation) through Enhavo's admin/resource layer, persist it, render it on a frontend route, and handle submissions through the bundle's controller or your own. If you only need generic Symfony forms, do not use this bundle — plain symfony/form is simpler and has actual documentation.
Because the bundle is part of a CMS rather than a form framework, patterns revolve around Enhavo's resource and block abstractions.
Defining a form as a resource. Forms are typically modeled as Doctrine-backed resources managed through the Enhavo admin. The usual pattern is:
src/Form/Type/ referencing the entity, and wire it in Resources/config/.validation.yaml in Resources/config/.Rendering a form. In a controller or block, load the form entity and hand it to a Symfony FormInterface built from the bundle's form type, then render through the bundle's Twig templates. If the bundle exposes a renderer service (check Resources/config/services.yaml for something like a FormRenderer or FormManager), prefer it over constructing forms manually — it will apply the CMS's field-type conventions consistently.
Extending field types. The clean extension point is Symfony's own form type extension mechanism:
class MyFieldTypeExtension extends AbstractTypeExtension
{
public static function getExtendedTypes(): iterable
{
return [SomeEnhavoFieldType::class];
}
public function buildView(FormView $view, FormInterface $form, array $options): void
{
$view->vars['my_attribute'] = $options['my_attribute'];
}
}
Register it with the form.type_extension tag and it will apply to every instance of that field type across the CMS, without forking the bundle.
Overriding templates. Use standard Symfony bundle override resolution: place templates under templates/bundles/EnhavoFormBundle/... mirroring the bundle's Resources/views structure. This is the safest customization path and survives composer updates. For per-form variation, prefer Twig blocks and a theme (form_theme) over copying the whole template.
Integrating with blocks. If your site uses Enhavo's block system, a form is often embedded as a block. The pattern is: a block type referencing a form entity, a template that calls the renderer, and a submission controller that redirects or re-renders with flash messages. Keep submission logic in your application service, not in the bundle's controller, so you can add spam protection, rate limiting, and custom persistence.
Handling submissions. The bundle likely provides a controller for POST handling. Decorating that service (Symfony service decoration) is a cleaner extension point than editing it:
services:
app.form_controller:
decorates: 'enhavo_form.controller.form' # verify actual service id
arguments: ['@app.form_controller.inner']
Use this to add CSRF hardening, honeypots, logging, or to route submissions into your own persistence layer.
Testing. Given the near-zero documentation and dependents, treat the bundle's own test suite (if present under src/Tests/ or tests/) as executable documentation. Write an integration test that boots the kernel, loads a form entity fixture, renders the form, and asserts on field names and validation behavior.
enhavo/enhavo repo.enhavo/form-bundle versions track the monorepo. Mixing versions across Enhavo packages is a common source of "class not found" and service-definition errors. Pin all enhavo/* packages to the same minor version in composer.json.config/bundles.php — EnhavoFormBundle should load after the core Enhavo bundles.doctrine.orm.mappings and Enhavo's mapping configuration.cache:clear. In dev, also check var/cache/dev/Container*/ to confirm your service tags registered.symfony/form plus your own persistence covers the requirement — for most non-CMS projects it does, with far less coupling.{{ dump(form.vars) }} and bin/console debug:container --tag=form.type to confirm which types are registered.form_theme overrides, (2) service decoration, (3) event subscribers on form events (FormEvents::PRE_SUBMIT, POST_SUBMIT), (4) subclassing bundle classes, (5) editing vendor code — never.Resources/config/services.yaml between versions before upgrading, and run your form integration tests as a gate.How can I help you explore Laravel packages today?