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

Form Annotation Bundle Laravel Package

kunicmarko/form-annotation-bundle

A Symfony bundle for defining forms with annotations on your entity classes. Configure fields and form options directly in code, reduce FormType boilerplate, and build forms automatically. Useful for rapid prototyping and smaller applications.

View on GitHub
Deep Wiki
Context7

Getting Started

Prerequisites check first. This bundle was last released in February 2018, targets the Symfony 3.3/4.0 era, and is archived. Before writing any code, confirm your project runs PHP 7.x with doctrine/annotations and a Symfony version old enough for the bundle's service definitions. On Symfony 5+ or PHP 8 you will hit deprecation and autowiring problems almost immediately.

Install and register.

composer require kunicmarko/form-annotation-bundle

Register the bundle manually (pre-Flex style) in app/AppKernel.php:

$bundles = [
    // ...
    new Kunicmarko\FormAnnotationBundle\FormAnnotationBundle(),
];

On a Flex app, add it to config/bundles.php.

Where to look first. The repository README is the only documentation; read it end to end before touching code, then inspect the Annotation/ directory (the annotation classes and their accepted options) and the service that reads them (typically a form factory/builder service). The tests are the most reliable specification of behaviour, since the README from 2018 may not match edge cases.

First use case. The intended workflow is to describe form fields declaratively on a class (usually an entity or form model) instead of hand-writing a FormType, then let the bundle build the form. Start with a single small entity and one controller action, render the form, submit it, and confirm the persisted result. Do not retrofit a large domain model on the first attempt — the annotation syntax and option merging are the parts most likely to surprise you.

Implementation Patterns

Annotate the model, build in the controller. The core pattern is field-level annotations that declare a form type and options, consumed by a builder service:

use Kunicmarko\FormAnnotationBundle\Annotation as Form;

class Post
{
    /** @Form\Field(type="text", options={"label": "Title"}) */
    private $title;

    /** @Form\Field(type="textarea", options={"attr": {"rows": 5}}) */
    private $body;
}

The exact annotation names and namespace alias come from the bundle's Annotation/ folder — verify them against the README before copying examples, as this package's docs are sparse.

Wire it into a CRUD action. Inject the bundle's form-building service into your controller (or fetch it from the container in a legacy app), pass the annotated object, and handle the request normally:

public function edit(Post $post, Request $request, FormBuilder $builder)
{
    $form = $builder->createForm($post);
    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {
        $this->em->flush();

        return $this->redirectToRoute('post_edit', ['id' => $post->id]);
    }

    return $this->render('post/edit.html.twig', ['form' => $form->createView()]);
}

Use DTOs for anything non-trivial. Because the annotations live on the class, they leak into your persistence layer. A common day-to-day pattern is a dedicated form model (DTO) annotated for the form, mapped to the entity in the controller. This keeps Doctrine metadata clean and makes it easy to have separate "create" and "edit" models with different field sets.

Mix with conventional form types. Treat the annotation-built form as a starting point: add fields imperatively with $form->add(...) after creation, or embed the generated form inside a larger FormType via a custom type. This is the pragmatic path when only part of a form fits the annotation model.

Reuse across contexts. Annotated classes are convenient for admin panels, prototypes, and internal tools where the same entity is rendered with slight variations. If two screens need materially different forms, prefer two DTOs over trying to conditionally mutate options at runtime.

Gotchas and Tips

  • Archived status is the dominant risk. No security fixes, no Symfony 5/6 support, zero dependents. Do not introduce it into a new project; if it is already in a codebase, plan an exit rather than building on it.
  • Annotations vs. attributes. On PHP 8, doctrine/annotations is deprecated and many teams have moved to native attributes. This bundle predates that entirely, so migration means rewriting the metadata layer — usually as explicit FormType classes, which is the better long-term answer anyway.
  • Cache invalidation. Annotation metadata is cached. After editing annotations, clear the cache (bin/console cache:clear) before concluding that a change "didn't work".
  • Silent failures are common. A mistyped annotation class or an unimported alias is often ignored rather than throwing. If a field is missing or has the wrong type, dump the built form ($form->getIterator() / debug:form) and verify the annotation is actually being read.
  • Option merging order. Symfony's type guessers, the bundle's defaults, and your annotation options interact. When attr, required, or label behave unexpectedly, add the field imperatively to confirm the annotation layer is the cause.
  • Doctrine coupling. Annotating entity properties means form concerns bleed into your domain model and can collide with validation annotations. Keep annotation-driven forms on DTOs where possible.
  • Debugging entry points. Use bin/console debug:container to find the builder service, debug:form to inspect resolved types, and the bundle's own tests as behavioural documentation. If the service will not autowire, define it explicitly in services.yaml — 2018-era service definitions rarely autowire cleanly on modern Symfony.
  • Extension points. The realistic customisation paths are decorating the form-builder service, registering a custom form type for an annotation value, or subclassing the annotation classes. Given the project is unmaintained, prefer decorating over forking.
  • Recommendation. For day-to-day work, the leverage is low: the same result is achieved with a few lines of FormType configuration, with no annotation cache, no PHP 8 friction, and no abandoned dependency. Use this bundle only to understand or maintain an existing legacy integration.
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.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
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