Creating a Role-Based Menu in Drupal

Mark Jarrell's picture

I was working today on creating a menu that is role-based. This is for the new Jones International University (http://www.jiu.edu) content management system, which is going to be Drupal-based. I was a little surprised that you can't easily do this when you're creating your individual menu items (say who gets to see what), but it's actually not too hard with a bit of PHP code added into the theme layer (in your page.tpl.php file). The current header is shown in the screenshot below.

The PHP code that is used to display individual menu items is actually pretty easy and intuitive. I had a couple of colleagues ask about it today, so I thought I'd share that here.

<?php
if (isset($primary_links)) {
  if (
in_array('administrator', $user->roles)) {
   
// Don't alter the array of primary links.  They see all of them.
   
print theme('links', $primary_links, array('class' => 'links primary-links'));
  } else {
   
$primary_links_by_role = array();
   
// Let's decide which menu items they get.
   
foreach ($primary_links as $value) {
      if (
$value['title'] == 'My Workspace' || $value['title'] == 'Courses' || $value['title'] == 'Degrees' || $value['title'] == 'Pages' || $value['title'] == 'People') {
       
// All roles get these tabs.
       
$primary_links_by_role[] = $value;
      } else if (
$value['title'] == 'Compliance' && in_array('compliance management', $user->roles)) {
       
$primary_links_by_role[] = $value;
      } else if (
$value['title'] == 'Materials' && in_array('materials management', $user->roles)) {
       
$primary_links_by_role[] = $value;
      } else if (
$value['title'] == 'Releases' && in_array('release management', $user->roles)) {
       
$primary_links_by_role[] = $value;
      }
    }
  print
theme('links', $primary_links_by_role, array('class' => 'links primary-links'));
  }
}
?>

The screenshot shows a user logged in with my "compliance management" role, so they get to see all of the basic tabs, plus the "Compliance" menu item.

Commenting on this Blog entry is closed.

Comments

custom module-based solution

For my first Drupal implementation, I am trying to avoid code hacks. Your solution seems very good and is straightforward enough to implement, however I was able to find a custom module which seems to accomplish the same thing.

Find it here: http://drupal.org/project/menu_per_role

Thanks for the great information!
Benjamin Lotter

Mark Jarrell's picture

Yeah, this is actually not a

Yeah, this is actually not a hack in any way. And I'm always striving for "one less module" on our sites if possible. So if something is easy to implement in the theme layer without slowing the site down significantly, I usually try to take that approach.

I can use this. Thanks for

I can use this. Thanks for sharing!

Mark Jarrell's picture

Sure thing. Enjoy!

Sure thing. Enjoy!