Profile picture for user admin
Daniel Sipos
29 Nov 2021

No doubt that by now you are familiar with the Drupal display and form modes. The former existed in previous versions of Drupal while the latter came in Drupal 8. As a matter of fact, you can check out this older article of mine in which I talk about custom form modes and how we can define and make entity types use them. If, of course, you are unfamiliar with the topic.

Today, however, I am going to tell you about a new hook introduced in Drupal 9.2 which allows us to swap out the form mode dynamically when the entity form is being rendered. Which, I have to admit, is something pretty cool. Many times in the past I had to alter forms and hide fields based various criteria such as access or context.

Let me paint you a picture with my imagination brush. Just to get an idea when this hook would shine. Imagine you have users on your site with a role called Customer. Admins can create/edit these users and they should be able to control all the fields on the user account. Which can include even things like remote_id. However, the users themselves, when they edit their own account, should not see all these fields but only a subset. For example, just the email and password. Maybe the timezone. Whatever. What you need in this case is to have a different form mode for when the user edits their own account and the default one can stay for when the admin edits the account.

We can now easily achieve this with hook_entity_form_mode_alter(). Before this new hook, a workaround for this kind of use case could be achieved with the more verbose hook_entity_form_display_alter(). This allows to hide or show various components (fields) from the form display depending on various conditions. But now, we can simply configure our form mode and switch it out entirely.

And it’s all very simple. Assuming you have created your User role called Customer and a form mode for the User account also called customer, we can implement the hook simply like this:

function module_name_entity_form_mode_alter(&$form_mode, Drupal\Core\Entity\EntityInterface $entity) {
  if ($entity instanceof \Drupal\user\UserInterface && $entity->hasRole('customer') && \Drupal::currentUser()->id() === $entity->id()) {
    $form_mode = 'customer';
  }
}

The hook receives the current form mode by reference so we can change it and the entity whose form is being built. All we have to do is check if we are looking at a User form and that the current user is the same as the user being edited. And we’re done. Customer users will now only see the intended subset of fields when editing their accounts. And when you add a new field, adjusting who gets to see it will be a matter of configuration instead of actual development work.

Hope this helps.

Profile picture for user admin

Daniel Sipos

CEO @ Web Omelette

Danny founded WEBOMELETTE in 2012 as a passion project, mostly writing about Drupal problems he faced day to day, as well as about new technologies and things that he thought other developers would find useful. Now he now manages a team of developers and designers, delivering quality products that make businesses successful.

Contact us

Comments

Kle 02 Dec 2021 14:27

cool HOOK - but in this case...

Thanks to clarify this new HOOK - maybe there is a theme-suggestion too which relates on the form-mode.

But to hide some fileds role-dependant I would prefer https://www.drupal.org/project/field_permissions ...

Add new comment