Once #2820359: Add #element_submit and #limit_element_submit just like #element_validate and #limit_validation_errors lands, we could proceed with adding an entity_form form element to core.
This is something we've reinvented several times across many modules (Commerce, Inline Entity Form, Paragraphs), etc.
The idea is simple, the form element gets an #entity, and in the process callback does:
$form_display = EntityFormDisplay::collectRenderDisplay($element['#entity'], 'default');
$form_display->buildForm($element['#entity'], $element, $form_state);
It also has a validate callback:
public static function validateForm(array &$element, FormStateInterface $form_state) {
$form_display = EntityFormDisplay::collectRenderDisplay($element['#entity'], 'default');
$form_display->extractFormValues($element['#entity'], $element, $form_state);
$form_display->validateFormValues($element['#entity'], $element, $form_state);
}
And a submit one:
public static function submitForm(array &$element, FormStateInterface $form_state) {
$form_display = EntityFormDisplay::collectRenderDisplay($element['#entity'], 'default');
$form_display->extractFormValues($element['#entity'], $element, $form_state);
$element['#entity']->save();
}
This form element could be used in all kinds of widgets and forms. Example:
$form['node'] = [
'#type' => 'entity_form',
'#entity' => $node,
];
Note: #entity is used instead of #default_value because we ran into issues otherwise. That might not be necessary for the core implementation, consider it an implementation detail.