1

I want do show/hide menu items based on a checkbox that the user selects when he/she registers.

I use profile2 for register. Should I use an external jquery script that calls on page load or should I use a hook_menu_alter() in my template file? I am not too familiar with Drupal code yet and appreciate any input.

1 Answer 1

1

Solution 1

Add a custom access callback to your paths, that will then determine whether or not the user should have access to a path.

Important: the code below will deny access to those paths. If you just wanted to show a slightly different menu and not block the access to those pages, see solution #2.

For example:

function YOUR_MODULE_menu_alter(&$items) {
  $items['your_path']['access callback'] = 'YOUR_MODULE_menu_access_callback';
}

function YOUR_MODULE_menu_access_callback(){
  global $user;
  if ($user->uid) {
    // Load user's Profile2 profile.
    $profile = profile2_by_uid_load($user->uid, 'NAME_OF_YOUR_PROFILE');
    // Allow access only if the user selected the checkbox.
    if (isset($profile->field_YOUR_FIELD[LANGUAGE_NONE][0]['value']) && $profile->field_YOUR_FIELD[LANGUAGE_NONE][0]['value']) {
      return TRUE;
    }
  }

  // This assumes that anonymous users should not have the access to a
  // particular menu.
  return FALSE;
}

This code would go in a custom module.


Solution 2

Add a simple theme_menu_link() override in your front-end theme, and skip rendering of those links.

Important: this will not prevent the access to those pages, it will just skip rendering of those list items. Also, you must be rendering the links using a menu, e.g. place a menu block somewhere in your theme, and not render the menu directly (e.g. theme('links__system_main_menu', ...) or theme('links__system_secondary_menu), ...)).

For example:

function YOUR_THEME_menu_link($variables) {
  global $user;
  $element = $variables ['element'];
  $sub_menu = '';

  // Exclude certain paths.
  if ($user->uid) {
    // Load user's Profile2 profile.
    $profile = profile2_by_uid_load($user->uid, 'NAME_OF_YOUR_PROFILE');
    // Allow access only if the user selected the checkbox.
    if (!isset($profile->field_YOUR_FIELD[LANGUAGE_NONE][0]['value']) || !$profile->field_YOUR_FIELD[LANGUAGE_NONE][0]['value']) {
      // Define the list of paths that should be excluded.
      $paths_to_exclude = array(
        'sample',
      );
      if (in_array($element['#href'], $paths_to_exclude)) {
        // Stop processing here, meaning this list item will not be included in
        // the menu.
        return;
      }
    }
  }

  if ($element ['#below']) {
    $sub_menu = drupal_render($element ['#below']);
  }
  $output = l($element ['#title'], $element ['#href'], $element ['#localized_options']);
  return '<li' . drupal_attributes($element ['#attributes']) . '>' . $output . $sub_menu . "</li>\n";
}

This code would go in the template.php file of your front-end theme.

4
  • Awesome answer, thank you very much. Option 1 is exactly what I am looking for. However, I am struggling a bit. The menu_alter seems to tackle the link + page. Perfect! But I have multiple links. Do I then create an array of my paths or create a new variable? Also, in the function, the field_MY_FIELD is printing array values. But only the first value gets printed. How do I print all my values? I tried using an if($profile... == 0){...} but I get an 'unidentified offset: 2' error if not all checkboxes are selected. Thanks. Commented May 25, 2015 at 14:14
  • 1/ multiple links - yes, that's why I created an array, so you can list multiple links in that array and use it as is. 2/ not sure I understand completely, would you mind clarifying that a bit and updating the question? Commented May 25, 2015 at 14:48
  • Thanks for your help! Had to use _module_implements_alter to get it working. Finally! Commented Jun 4, 2015 at 14:33
  • Sure, glad it helped! Commented Jun 4, 2015 at 18:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.