How to show and hide menu based on custom access logic in Drupal Custom module
One of the basic requirements with Drupal websites having multiple roles is that customers need to show certain links in the menu to a particular role and also need to write custom access control logic in order to decide whether the user can see the menu link or not.
If you want to show and hide menu links based on role and without any custom logic, a you can use below module which has good administrative UI ,
https://www.drupal.org/project/menu_item_role_access
Here we are going to discuss access restrictions in below cases.
- Show/hide menu item to the particular role of users based on custom logic
- Restrict access to custom module link in *.routing.yml using custom logic
Before going to discuss in detail, I am going to create two roles and assign these roles to two users.
Here I have created student role and teacher role.
Now we are going to create a new menu item News in Main navigation menu.
Here we are providing menu Link as a custom link in our custom module routing.yml.
So in my custom module I have a route as below.
digitalnadeem_menupermission.permissioncheck: path: '/redirect/google' defaults: _controller: '\Drupal\digitalnadeem_menupermission\Controller\MenuPermissionController::redirectUrl' _title: 'Permission Check' requirements:
here digitalnadeem_menupermission is the module name and MenuPermissionController is the controller.
Now I am going to provide a custom access logic here .so for that we have to add requirements as below.
digitalnadeem_menupermission.permissioncheck: path: '/redirect/google' defaults: _controller: '\Drupal\digitalnadeem_menupermission\Controller\MenuPermissionController::redirectUrl' _title: 'Permission Check' requirements: _custom_access: '\Drupal\digitalnadeem_menupermission\Controller\MenuPermissionController::checkUserAccess'
Here checkUserAccess is the function where we are writing our custom logic to decide whether do we need to show the menu or not.
in controller , first import below classes
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Session\AccountInterface;
also for redirecting to external link we have to use below reference.
use Drupal\Core\Routing\TrustedRedirectResponse;
our custom access check function will be as below
public function checkUserAccess(AccountInterface $account) { /* your custom logic */ $roles = $account->getRoles(); if (!in_array('student', $roles)) { return AccessResult::forbidden(); } return AccessResult::allowed(); }
Here in my custom logic I am restricting access if user role is not student.
So now login as student user, you can see news menu item in header menu section.
Also login as teacher , new menu item is not there.
By default anonymous user and admin user can see the menu item. You can control this by adding additional conditions.
Here I am showing an example using roles check. You can create whatever logic you want , then use AccountInterface in order to allow and forbidden access.
Here Drupal internally handle hiding/showing menu item based on access requirement of the link provided.