Display Modes: View Modes and Form Modes

Last updated on
16 August 2023

Display modes

Display modes (found at admin/structure/display-modes) exist to provide different presentations of Content Entities for either viewing or editing. The two types of display modes are "view modes" and "form modes." Both of these display mode types—view modes and form modes—are examples of "configuration entities." Here is an example of an exported view mode.

uuid: 15dc7aa9-13fd-4412-9c06-06d09f915d08
langcode: en
status: false
dependencies:
  module:
    - node
id: node.full
label: 'Full content'
targetEntityType: node
cache: true

reference: core.entity_view_mode.node.full.yml

The main property to take note of is the "targetEntityType" property. Each display mode (view mode or form mode) is associated with one, and only one, type of Content Entity. By convention there are labels that get used for multiple display modes. For instance, Drupal Core’s standard profile uses the word “Full” in the labels of view modes for the content entity types of node, custom blocks and comments.

View modes and view displays

  • Administered in aggregate at: /admin/structure/display-modes/view
  • Enabled per bundle under "Custom display settings" at urls like: /admin/structure/types/manage/page/display (where ‘page’ is a bundle of the node entity)
  • Configured per view mode per bundle at urls like: /admin/structure/types/manage/page/display/teaser (where ‘page’ is a bundle of the node entity and ‘teaser’ is a view mode)

(View modes as a concept predate Drupal 8. They were present in Drupal 7. Drupal 6 had the concept of “build modes.”  In Drupal 7 we have both the field and the field widget on the "Manage fields" tab of any content type. Now this has been split into two tabs: "Manage fields" and "Manage form display." The "Manage display" tab is still the same as it was in Drupal 7.)

View modes exist to allow Drupal site building tools like Entity Reference fields to request a given entity be rendered in a certain way. For instance, suppose that ‘song’ and ‘artist’ are each node types and that song contains a reference field to artist. The ‘full’ display of the song node may need to render the ‘teaser’ display of the artist node. In this example ‘teaser’ is a view mode used by the artist node and ‘full’ is the view mode used by the song.

It is usually the case that if a site builder wants to display the artist node bundle in the teaser view mode then that site builder will have made configuration specific to artist and teaser. This can be done by going to the “Manage Display” tab with the entity bundle configuration page. An example of this page in the Drupal Core’s standard install profile is /admin/structure/types/manage/article/display

On this page a site builder has the option to enable customized field display settings for the bundle (field order and field formatter usage) on a per view mode basis. It is not required that all view modes have specific customizations made for all bundles. In this example, only the view modes “RSS” and “Teaser” have their own specific settings. All other view modes fall back to the “default” configuration. The association between an entity type bundle and view mode is called a View Display. @see EntityViewDisplayInterface

Screenshot of checkboxes enabling view modes for a content type

Form modes

  • Administered in aggregate at: /admin/structure/display-modes/form
  • Enabled per bundle at urls like: /admin/structure/types/manage/page/form-display (where ‘page’ is a bundle of the node entity)
  • Configured per form mode per bundle at URLs like: /admin/structure/types/manage/page/form-display/simple (where ‘page’ is a bundle of the node entity and ‘simple’ is a form mode).

Like view modes, form modes allow for multiple sets of field widget orderings and customizations, just as view modes allow for different orderings and customization of field formatters. This gives us more flexibility over how things will appear when someone is looking at the add/edit form of any content types.

In addition to content types, we can also manage view modes for other entity types like users, taxonomy, comments, and custom blocks. 

A common need is for user registration forms to not display all user fields. Once a user is registered, they will have access to an Edit Profile form that has additional fields. This is an example of this kind of configuration:

  • Click Add Field from /admin/config/people/accounts/fields
  • Next screen select a field type, List(Text)
  • Give it a Label: "Subscription List"
  • Click "Save and continue"
  • Fill out the Allowed values list, for example:
    • 1|News
    • 2|Important Announcements
    • 3|Offers, Discounts, Specials
    • 4|Partner Messages
  • Click Save
  • Make it a Required field
  • Select all four items as default, click save.
  • Next, click the "Manage form display" tab
  • At the bottom of the field list is a section labeled "Custom Display Settings", expand this.
  • In the "Use custom display settings for the following form modes" field enable "Register" and click Save.
  • Now you'll have a second tab menu labeled "Register".
  • Disable the Subscription List field by dragging it to the "Disabled" section. Click save.
  • Go to the Manage Display tab to make sure that the Subscription List field is enabled.

Log out of the site and visit the registration form. The Subscription List field will not be visible.
Once logged in, the Subscription List field will be available in the update profile form.

Form operations

Form operations allow for defining which classes should be used for forms like a node delete form. The class used to delete a node is different from the class used to edit a node. Operations are defined in an entity’s annotations. Here is an example that will map 2 custom form operations -- as well as the "default" form mode -- to the same form MyEntityForm. To use form widgets, make sure this form extends ContentEntityForm.

/**
 * @ContentEntityType(
 *   id = "myentity",
 *   handlers = {
 *     "form" = {
 *       "default" = "Drupal\myentity\Form\MyEntityForm",
 *       "add" = "Drupal\myentity\Form\MyEntityForm",
 *       "edit" = "Drupal\myentity\Form\MyEntityForm",
 *       "delete" = "Drupal\myentity\Form\MyEntityDeleteForm",
 *     },
 *   },
 * )
 */

If you need to add or alter available form operations in existing entities you can use hook_entity_type_build and hook_entity_type_alter .

To display a form with a custom form mode, use _entity_form in your route. For example, to display the custom "edit" form of the MyEntity, use this route:

entity.myentity.edit_form:
 path: '/myentity/{myentity}/edit'
 defaults:
   _entity_form: myentity.edit
   _title: 'Edit MyEntity'
 requirements:
   _permission: 'edit myentity entities' 

The value of _entity_form is the entity type and the form operation separated by a dot. These route definitions by default are created by DefaultHtmlRouteProvider which uses the link templates defined in the entity annotation:

/**
 * @ContentEntityType(
 *   id = "myentity",
 *   links = {
 *     "canonical" = "/myentity/{myentity}",
 *     "delete-form" = "/myentity/{myentity}/delete",
 *     "edit-form" = "/myentity/{myentity}/edit",
 *   },
 * )
 */

If the add-form link template exists, a route definition for the add form will be created. This definition will use _entity_form with the add form operation if it is defined and the default if it is not. Similarly, if the edit-form link template exists, a route definition for the edit form will be created. This definition will use _entity_form with the edit form operation if it is defined and the default if it is not. Because the definition itself handles the fallback, the HTML form controller used by _entity_form requires the operation to exist, it does not fall back to the default operation. This could be considered a bug. See #2511720: Allow form modes to use default operation if a form operation is not explicitly set.

As mentioned, some form operations will define their own classes but the add/edit/default form operations typically use widgets. As discussed in the previous section, the configuration of these are stored in entity form displays which are keyed by entity type, entity bundle and form mode. So the system needs to find out which form mode to use for a particular operation. This is very simple: the form operation itself is used as the form mode and if it is not defined then the default form mode is used instead.

Note the $operation argument of EntityAccessControlHandlerInterface::access and ::fieldAccess methods have nothing to do with the form operation (or even with each other).

Help improve this page

Page status: No known problems

You can: