n How to add custom mode form to entities in Drupal 8 & 9 | CodimTh

Please Disable Your Browser Adblock Extension for our site and Refresh This Page!

our ads are user friendly, we do not serve popup ads. We serve responsible ads!

Refresh Page
Skip to main content
On . By CodimTh

How to add custom mode form to entities in Drupal 8 & 9

in this article we will discover how to use form modes, from their creation to their use to customize the input of a user's information, for example.

The creation of form modes is quite simple and can be done in a few clicks, from the administration interface (from the path /admin/structure/display-modes/form).

Let's add a new form mode that we will call for example Profil.


form display


And the User entity now has a new Profil form mode, in addition to the existing Register form mode (used for the registration form on a Drupal 8 site).

And we find our new form mode on the configuration page of the forms display (path /admin/config/people/accounts/form-display) of Drupal users.


custom display settings


After we activate Profil mode then we can configure which fields will be rendered in this form mode. For example, we can configure this form mode to fill only the First name, Last name, Picture and Job fields that have been created for the User entity.


form display


To finalize this we will use a custom module that we will call mymodule.

Let's create mymodule.info.yml file:

type: module
name: My Module
description: My Module description
package: Custom
core_version_requirement: ^8.8.0 || ^9.0


This module will allow us to declare our new form mode for the User entity, and to create a route, as well as a menu, which will allow us to access and complete our form.

First, let's declare this form mode and associate a Class with it, from the file mymodule.module:


 * Implements hook_entity_type_build().
function mymodule_entity_type_build(array &$entity_types) {
  $entity_types['user']->setFormClass('profil', 'Drupal\user\ProfileForm');


Here we associate the default form class User ProfileForm with our profil form mode. We could just as easily have used a Class ProfilCustomForm by extending the Class AccountForm.

All we have to do now is create a route, from the file mymodule.routing.yml, and we can then access our form.

  path: '/user/{user}/profil'
    _entity_form: 'user.profil'
    _title: 'Profil'
    _entity_access: 'user.update'
    user: \d+
    _admin_route: FALSE


Now we will create a dynamic menu entry in the user account menu, in order to give an access link to users. In the file mymodule.links.menu.yml, let's add an entry to create the corresponding menu link.

  title: 'Profil'
  weight: 1
  route_name: mymodule.user.profil
  base_route: entity.user.canonical
  menu_name: account
  class: Drupal\mymodule\Plugin\Menu\ProfilUserBase


What is notable here, in this menu entry, is the class property that will allow us to define the dynamic {user} parameter of the route corresponding to this menu entry. 

This ProfileUserBase Class will only return the ID of the accessed user, if the menu link is displayed on the user's page, or return the ID of the connected user if it is not, otherwise.



namespace Drupal\mymodule\Plugin\Menu;

use Drupal\Core\Menu\MenuLinkDefault;
use Drupal\Core\Url;
use Drupal\user\UserInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Menu\StaticMenuLinkOverridesInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;

 * Profile Menu Link
class ProfilUserBase extends MenuLinkDefault implements ContainerFactoryPluginInterface {

   * The entity type manager.
   * @var \Drupal\Core\Entity\EntityTypeManager
  protected $entityTypeManager;

   * The current route match service.
   * @var \Drupal\Core\Routing\CurrentRouteMatch
  protected $currentRouteMatch;

   * The current user.
   * @var \Drupal\Core\Session\AccountInterface
  protected $currentUser;

   * Constructs a new MenuLinkDefault.
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin_id for the plugin instance.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\Core\Menu\StaticMenuLinkOverridesInterface $static_override
   *   The static override storage.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager service.
   * @param \Drupal\Core\Routing\RouteMatchInterface $current_route_match
   *   The current route match service.
   * @param \Drupal\Core\Session\AccountInterface $current_user
   *   The current user.
  public function __construct(array $configuration, $plugin_id, $plugin_definition, StaticMenuLinkOverridesInterface $static_override, EntityTypeManagerInterface $entity_type_manager, RouteMatchInterface $current_route_match, AccountInterface $current_user) {
    parent::__construct($configuration, $plugin_id, $plugin_definition, $static_override);
    $this->entityTypeManager = $entity_type_manager;
    $this->currentRouteMatch = $current_route_match;
    $this->currentUser = $current_user;

   * {@inheritdoc}
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(

  public function getRouteParameters() {
    return ['user' => $this->getUserIdFromRoute()];

   * {@inheritdoc}
  public function getCacheContexts() {
    return ['user', 'url'];

   * Get the Account user id from the request or fallback to current user.
   * @return int
  public function getUserIdFromRoute() {
    $user = $this->currentRouteMatch->getParameter('user');
    if ($user instanceof AccountInterface) {
      return $user->id();
    elseif (!empty($user)) {
      $user = $this->entityTypeManager->getStorage('user')->load($user);
      if($user instanceof AccountInterface) {
        return $user->id();

    return $this->currentUser->id();



Finally here is an example of our profil form:

form display




Riadh Rahmi

Senior Web Developer PHP/Drupal & Laravel

I am a senior web developer, I have experience in planning and developing large scale dynamic web solutions especially in Drupal & Laravel.

Web Posts


Page Facebook