I'm trying to consolidate my form processing by entity_type, without rebuilding the forms (just using the default forms provided by Drupal.

I have dynamic routes pointing to a _controller::method. I've tried:

  • A. \Drupal::service('entity.form_builder')->getForm($group_content, 'edit', $data) but this just returns a render array, no instance.
  • B. \Drupal::formBuilder()->getForm('\Drupal\group\Entity\Form\GroupContentForm') but this is the wrong class path and i can't figure out how I could reference any entity:bundle:id by any pattern (i've tried many)
  • C. Changed the route to use _form or _entity_form extending FormBase (instead of a controller), but it seems these require the buildForm method to defined the form's full field list (which defeats the purpose of my question).

What is the best approach to expose edit/add/delete process handlers for multiple bundles / entity_type in a single class?

1 Answer 1


A. EntityFormBulder::getForm is just a shortcut for instantiating the form object, injecting the entity and building the render array. You can split this up:

  public function getForm(EntityInterface $entity, $operation = 'default', array $form_state_additions = []) {
    $form_object = $this->entityTypeManager->getFormObject($entity->getEntityTypeId(), $operation);

    $form_state = (new FormState())->setFormState($form_state_additions);
    return $this->formBuilder->buildForm($form_object, $form_state);

B. You have to inject the entity before you can build an entity form, see the steps above.

C. _entity_form is for integrating an entity form in a route, then the route parameter is upcasted and injected into the form automatically, see How to Inject entity object in EntityForm

The best approach is C. (standard pattern) and refactor the OOP code.

BTW if you don't find a OOP solution or if it is too complicated then you could simply add a custom process callback to $form['#process'] in a form alter hook to all or specific entity forms.

  • i'm using Drupal entirely decoupled from it's front-end, so pretty sure $form['#process'] won't help me right?
    – E.A.T
    Commented Jul 5, 2019 at 14:38
  • i have been able to use _entity_form to invoke my custom class extending Drupal\node\NodeForm but it only invokes buildForm, despite my route only handling PATCH methods. The route also declares parameters to be upcast, so maybe that's a conflict with this form approach?
    – E.A.T
    Commented Jul 5, 2019 at 14:41
  • additionally, i looked at EntityFormBulder::getForm but what it returns won't work for submitForm unless the form object can be populated with the user's data?
    – E.A.T
    Commented Jul 5, 2019 at 16:57
  • all you points are correct, thank you. but they don't answer my question relating to API endpoints and invoking processForm directly.
    – E.A.T
    Commented Jul 7, 2019 at 17:16
  • I don't think you can invoke processForm() directly, at least not without providing a full form build. For the overall picture, how to decouple entity forms and expose them as API endpoint, this might help to exclude things, but doesn't answer how to do it. Perhaps it needs some core changes first, for example drupal.org/project/drupal/issues/2913372
    – 4uk4
    Commented Jul 7, 2019 at 18:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.