Drupal - How do I programmatically generate an entity form?

You can use the entity form builder service. I was able to load the user form this way (with $entity being the current user):

$entity = User::load($uid);
$user_form = \Drupal::service('entity.form_builder')->getForm($entity, 'default');

If you want to get the user register form (which is basically an entity form without a saved entity), you can just use the create method on your entity class before passing it to the form:

$entity = User::create();
$user_form = \Drupal::service('entity.form_builder')->getForm($entity, 'default');

Entity forms don't work without an entity. If you want an empty form then use a newly created entity instance. You can use this example from the node entity:

/**
 * Provides the node submission form.
 *
 * @param \Drupal\node\NodeTypeInterface $node_type
 *   The node type entity for the node.
 *
 * @return array
 *   A node submission form.
 */
public function add(NodeTypeInterface $node_type) {
  $node = $this->entityManager()->getStorage('node')->create(array(
    'type' => $node_type->id(),
  ));

  $form = $this->entityFormBuilder()->getForm($node);

  return $form;
}

The entity form builder is injected in the controller base class. So usually you use a controller to build entity forms.

When creating a node you need to define a bundle (content type), for which the entity form will be built. If your entity has no bundles you can use an empty array.


Comments

Comments need more work, because they are attached to an entity field.

Example how to build a form for the comment field of a node:

$comment = $this->entityTypeManager()->getStorage('comment')->create([
  'entity_type' => 'node',
  'entity_id' => $node->id(),
  'field_name' => 'comment',
]);
$build = $this->entityFormBuilder()->getForm($comment);

Or the same outside of a controller without injected services:

$comment = \Drupal::entityTypeManager()->getStorage('comment')->create([
  'entity_type' => 'node',
  'entity_id' => $node->id(),
  'field_name' => 'comment',
]);
$build = \Drupal::service('entity.form_builder')->getForm($comment);

Just to clarify, the below code does work for me in Drupal 8.2.x:

$form = \Drupal::formBuilder()->getForm(Drupal\user\Form\UserLoginForm::class);

Tags:

Forms

8