How to programmatically render entity form

Components

Programatically rendering entity form in Drupal 8, 9 and 10 is easy, provided that you want to render it using the default form mode.

// Load existing node
$node = \Drupal\node\Entity\Node::load(1);
// or create a new node
$node = \Drupal::entityTypeManager()->getStorage('node')->create(['type' => 'article']);

$form = \Drupal::service('entity.form_builder')->getForm($node);

If you want to render it using any other form mode like this for example:

$node = \Drupal\node\Entity\Node::load(1);
$form = \Drupal::service('entity.form_builder')->getForm($node, 'compact');

you will have to alter the entity definition and add your own form handler. Otherwise, you'll get the following error:

Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException: The "node" entity type did not specify a "compact" form class.

To add your own form class you can use the hook_entity_type_alter hook like this:

/**
 * Implements hook_entity_type_alter().
 *
 * Alters the entity definition and adds our own form handlers.
 */
function MY_MODULE_entity_type_alter(array &$entity_types) {
  $form_modes = \Drupal::service('entity_display.repository')
    ->getAllFormModes();

  foreach ($form_modes as $entity_type => $display_modes) {
    if ($entity_type !== 'node') {
      continue;
    }

    $type = $entity_types[$entity_type];
    foreach ($display_modes as $machine_name => $form_display) {
      if (isset($type->getHandlerClasses()['form']['default'])) {
        $default_handler_class = $type->getHandlerClasses()['form']['default'];
        $type->setFormClass($machine_name, $default_handler_class);
      }
    }
  }
}

In summary, while rendering an entity form programmatically in Drupal 8, 9 and 10 is straightforward with the default form mode, using custom form modes requires altering the entity definition and specifying appropriate form handlers to avoid errors. 

About the Author

Goran Nikolovski is a web and AI developer with over 10 years of expertise in PHP, Drupal, Python, JavaScript, React, and React Native. He founded this website and enjoys sharing his knowledge.