Replacing a specific menu item

The question:

So, I understand how to target a specific menu using the following to add a custom code.

<?php

wp_nav_menu(
 array(
  'menu' => 'Project Nav',
  // do not fall back to first non-empty menu
  'theme_location' => '__no_such_location',
  // do not fall back to wp_page_menu()
  'fallback_cb' => false
 )
 );

?>

Question I have is the following.

Let say I have a menu called “primary”. Within this menu, there are 4 menu items (picture below).

enter image description here

One of the items is called “Profile”.

I want to replace the word “Profile” with the following code which shows user profile photo instead of the word “Profile”.

    <?php global $my_profile; ?>
    <?php if (is_user_logged_in()) : ?>
    <div class="img" data-key="profile"><?php echo get_avatar( get_current_user_id(), 64 ); ?></div>
    <?php endif; ?>

So, the final result would look like this:

enter image description here

Now, how can I specifically target a menu item title?

EDIT:

So, I got the following based and I am not sure why it is not working.

function nav_replace_wpse_189788($item_output, $item, $args) {
 //var_dump($item_output, $item);
 if( $args->theme_location == 'primary' ){
  return $items;

   if ('royal_profile_menu_title' == $item->title) {
    global $my_profile;

    if (is_user_logged_in()) { 
      return '<div class="img" data-key="profile">'.get_avatar( get_current_user_id(), 64 ).'</div>';
        }
    }
  }
   return $item_output;
 }
 add_filter('walker_nav_menu_start_el','nav_replace_wpse_189788',10,2);

Here is my logic. First target the “primary” menu, then look for item title “royal_profile_menu_title” then replace the word title with the output

(My menu title is “royal_profile_menu_title”: Picture below)
enter image description here

Any

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

This is relatively easily done using the walker_nav_menu_start_el filter (without all that PHP tag spam):

function nav_replace_wpse_189788($item_output, $item) {
  //   var_dump($item_output, $item);
  if ('Profile' == $item->title) {
    global $my_profile; // no idea what this does?
    if (is_user_logged_in()) { 
      return '<div class="img" data-key="profile">'.get_avatar( get_current_user_id(), 64 ).'</div>';
    }
  }
  return $item_output;
}
add_filter('walker_nav_menu_start_el','nav_replace_wpse_189788',10,2);

Note: I had to edit your code to return a string, not echo one. You may need to tweak the if conditional. Uncomment the var_dump() to see what you have to work with.

Method 2

Presonally, I would use some CSS workaround. In menu administration you can add CSS class to menu item (if the field is not displayed, you can find it in Screen Options), for example “profile-link”.

And than you can add something like this to your template HEAD section:

<?php
$avatar = get_avatar_url( get_current_user_id(), array('size' => 64) ); // from WP 4.2
$image_url = $avatar['url'];
?>

<style type="text/css">
.menu li.profile-link { background-image: url(<?php echo $image_url ?>); /* + another CSS*/  }
.menu li.profile-link span { display: none; }
</style>

And add to your wp_nav_menu function 'link_before' => '<span>', 'link_after' => '</span>' options.

Not tested, but it should do the job.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment