Not every field belongs on every form. A "created" timestamp might make sense on a display page but not on an add form; an internal notes field might belong on the edit form but never the quick-add version. Drupal handles this with form displays — configuration, not code, that controls which fields appear, in what order, and with which widget, per form mode.
What you'll learn in this lesson
- What a form display actually is, and how it's different from a view display
- How the "default" form mode relates to custom form modes
- Where form-display configuration actually lives on disk
- Why this is almost always the right tool before you reach for a code-level override
Form displays are per entity type + bundle + mode
Every content entity type gets a "default" form display automatically. If your entity type supports bundles (content types, in node's case), each bundle can have its own. On top of "default," you can define additional named form modes — a "quick_add" mode with only three fields, for example — and each mode gets its own independent field layout.
What the configuration actually looks like
langcode: en
status: true
dependencies:
module:
- content_entity_example
id: content_entity_example_contact.content_entity_example_contact.default
targetEntityType: content_entity_example_contact
bundle: content_entity_example_contact
mode: default
content:
name:
type: string_textfield
weight: 0
region: content
first_name:
type: string_textfield
weight: 1
region: content
hidden:
created: true
changed: true
Two sections matter here: content lists every field that's visible, with its widget type and display order (weight); hidden lists fields that exist on the entity but are deliberately excluded from this particular form. Reordering fields, swapping a widget, or hiding a field is entirely a matter of editing this config — no PHP, no touching ContactForm.php at all.
buildForm() override (as in earlier lessons) should be reserved for logic config can't express, like the language-selector or uniqueness-validation examples from this section.See it for yourself
If your site has Field UI enabled, visit /admin/structure/content-entity-example-contact-type/form-display (or the equivalent "Manage form display" tab for your entity type) and try dragging a field to reorder it — that action writes directly to the YAML shape shown above.
Quick check: you want the "Language" field this section's earlier lessons added via
buildForm()to also be reorderable through the form-display UI, like every other field. What would that take? (It would need to become a real field on the entity — defined inbaseFieldDefinitions()— rather than a form element hand-added in PHP, since only genuine entity fields participate in form-display configuration.)
Key takeaways
- Form displays are per entity type, per bundle, per form mode — "default" always exists automatically.
- The
content/hiddensplit in a form display's YAML controls exactly which fields appear and in what order, without any PHP. - Reordering fields and swapping widgets should go through form-display config first; reach for a
buildForm()override only for logic config genuinely can't express. - Only real entity fields (declared in
baseFieldDefinitions()) participate in form-display configuration — form elements added manually in PHP don't.
Coming up next
You've now seen the config-driven side of entity forms. Next, we return to the code-driven side one more time: hook_entity_form_alter(), for changes that need to reach across every entity form on the site, not just one form class.