4

I would like to achieve what Acquia did on https://dev.twitter.com/. When you sign in, you can see the user picture and the user name in the right end of the menu bar and that is what I need.

I made just some basic attempts yet:

First I tried to use the Menu Token module. Tried to put user picture and user name tokens into the title. Then I realized, that you can't put html in the menu item title as it goes through check_plain() (and it is good that way). Other problem with this was, that the menu item was shown for Anonymous users as well, and the user name was "Anonymous".

I'm using the Omega theme.

The twist on the whole problem is, that I would like to use the Superfish module as well (drop-down as on the Twitter site), and it has its own theme function for building/rendering the menu items.

I can think of a possible solution, that would be a custom theme function and a menu link alter, so that I add an image besides the title. But the Superfish module won't handle the image added to the "raw" link. Correct me if I am wrong...

1
  • 1
    How about putting it in a template? Aug 31, 2011 at 12:27

4 Answers 4

4

One method of doing this is to override theme_menu_link() in your template.php file. Specifically, we will be looking for the "My account" link and changing that the text to the username and adding the image.

Add the following to your template.php in your Omega subtheme:

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

  if ($element['#below']) {
    $sub_menu = drupal_render($element['#below']);
  }
  $title = '';
  // Check if the user is logged in, that you are in the correct menu,
  // and that you have the right menu item
  if ($user->uid != 0 && $element['#theme'] == 'menu_link__user_menu' && $element['#title'] == t('My account')) {
    $element['#title'] = $user->name;
    // Add 'html' = TRUE to the link options
    $element['#localized_options']['html'] = TRUE;
    // Load the user picture file information; Unnecessary if you use theme_user_picture()
    $fid = $user->picture;
    $file = file_load($fid);
    // I found it necessary to use theme_image_style() instead of theme_user_picture()
    // because I didn't want any extra html, just the image.
    $title = theme('image_style', array('style_name' => 'thumbnail', 'path' => $file->uri, 'alt' => $element['#title'], 'title' => $element['#title'])) . $element['#title'];
  } else {
    $title = $element['#title'];
  }
  $output = l($title, $element['#href'], $element['#localized_options']);
  return '<li' . drupal_attributes($element['#attributes']) . '>' . $output . $sub_menu . "</li>\n";
}

This produces the following html for the menu item in question (my thumbnail image style is set to scale and crop 28 x 28):

<li class="first last expanded"><a href="/user" title=""><img typeof="foaf:Image" src="path/to/image" width="28" height="28" alt="username" title="username">username</a></li>

The rest is just css and possibly javascript.

1
  • Instead of using $element['#title'] == t('My account')) in the condition, checking against $element['#href'] should be safer, otherwise I am accepting this answer! Thanks!
    – Temaruk
    Jun 28, 2013 at 11:53
4

I came across this issue too and just used the Menu HTML module in conjunction with Menu Tokens. This very simple module adds a checkbox to the menu item edit form and allows the admin to add html to the menu item title. This way you can use [current-user:picture][current-user:name] and the users picture (avatar) will show.

1
  • Of course you will have to set avatar to the right size on the user's configuration screen.
    – Druvision
    Dec 5, 2013 at 8:47
2

For D7 Bootstrap 3 users who want to use profile picture and username as a parent menu item for a "my account" menu.

I hacked the following together from the above two code samples, along with a few lines from the bootstrap menu include file menu-link.func.php.

I'm sure it's not perfect, but it's working in my install. I'm using a module (with included theme override function) instead of template.php. Note my imagestyle "avatar40" should be replaced with your own imagestyle name.

function MYMODULE_menu_link(array $variables) { // overrides the default "my account" link with avatar and name
  global $user;
  $element = $variables['element'];
  $sub_menu = '';
  $caret_text = '';

  if ($element['#below']) {
    unset($element['#below']['#theme_wrappers']); // remove default html menu wrappers
    $sub_menu = '<ul class="dropdown-menu">' . drupal_render($element['#below']) . '</ul>'; // add wrapper <ul> tag with bootstrap class
    $caret_text = ' <span class="caret"></span>'; // only show caret if submenu exists
  }
  $title = '';
  // Check if the user is logged in, that you are in the correct menu,
  // and that you have the right menu item
  if ($user->uid != 0 && $element['#theme'] == 'menu_link__user_menu' && $element['#title'] == t('My account')) {
    $element['#title'] = $user->name;
    // prepare bootstrap attributes for wrapper <li>, and then the <a> tag it contains
    $element['#attributes']['class'][] = 'dropdown';
    $element['#attributes']['class'][] = 'user-picture';
    $element['#localized_options']['html'] = TRUE;
    $element['#localized_options']['attributes']['class'][] = 'dropdown-toggle';
    $element['#localized_options']['attributes']['data-target'] = '#';
    $element['#localized_options']['attributes']['data-toggle'] = 'dropdown';
    // manually prepare picture, <a> tag with image reference, username (theme_user_picture won't work due to nested <a> tag)
    if (!empty($user->picture)) {
      $fid = $user->picture; 
      $file = file_load($fid);
      $title = theme('image_style', array('style_name' => 'avatar40', 'path' => $file->uri, 'alt' => $element['#title'], 'title' => $element['#title'])) . $element['#title'] . $caret_text;
    }
    else {
      $title = $element['#title'] . $caret_text;
    }
  } 
  else {
    $title = $element['#title'];
  }
  $output = l($title, $element['#href'], $element['#localized_options']);
  return '<li' . drupal_attributes($element['#attributes']) . '>' . $output . $sub_menu . "</li>\n";
}
1
  • 1
    Even if your answer is dedicated for Bootstrap users I am surprised that nobody has alerady upvote it ;). Your code is working very well with drupal bootstrap 7.3.3 & bootstrap framework 3.3.5 . Thank you. (ps: here, I've added the code on template.php of my subtheme).
    – xaa
    Dec 16, 2015 at 12:11
1

Using Menu HTML + Menu Tokens breaks Menu Item Visibility. Code above works, except if user didn't set a picture. For that I do:

// Check if the user is logged in, that you are in the correct menu,
// and that you have the right menu item
if ($user->uid != 0 && $element['#title'] == t('User Menu')) {
  $element['#title'] = $user->name;
  // Add 'html' = TRUE to the link options
  $element['#localized_options']['html'] = TRUE;
  //isset($user->picture) always returns true, don't know why. had to use !empty
  if (!empty($user->picture)) {
     $url = file_load($user->picture)->uri;
  }
  else if (variable_get('user_picture_default', ''))
  {
     $url = variable_get('user_picture_default','');
  }
  else
  {
     $url = "public://avatars/anon.png";
  }
  $title = $element['#title'] . theme('image', array('path' => $url, 'width' => '30px', 'height' => '30px'));
} else {
  $title = $element['#title'];
}

$output = l($title, $element['#href'], $element['#localized_options']);
1
  • Is it applicable in non bootstrap theme as well?
    – Umair
    Sep 23, 2016 at 14:03

Your Answer

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

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