wp_get_nav_menu_items() current menu item

When displaying a menu in WordPress I sometimes find it pleasant to use the wp_get_nav_menu_items() function. This function returns only an array of menu item objects of the corresponding menu. So it allows you to build your custom menu exactly the way you want, without dealing with WordPress predefined output.

However, if you would use the function wp_nav_menu() you benefit from a built-in “current menu” conditional logic which lets you know which menu item is active through a CSS class added to the current menu list item. When using wp_get_nav_menu_items you have to create this logic yourself.

Solution 1: Queried object id

When building your custom menu with wp_get_nav_menu_items() you can create this current menu item functionality by simply checking the queried object id of the current page and compare it to each menu item’s object id.

// Check if menu exists
if ( $menu_items = wp_get_nav_menu_items( 'menu' ) ) {
   
   // Loop over menu items
   foreach ( $menu_items as $menu_item ) {

      // Compare menu object with current page menu object
      $current = ( $menu_item->object_id == get_queried_object_id() ) ? 'current' : '';
      
      // Print menu item
      echo '<li class="' . $current . '"><a href="' . $menu_item->url . '">' . $menu_item->title . '</a></li>';
   }
}

Solution 2: Request URI path

There is only one problem when you use the queried object id to check whether the menu item is the current page, namely; when you add link menu items to, for example, a post type archive. These pages have no object id. In that case, it is a better option to compare the path of the request URI with the URL of the menu item. You can do this as follows:

// Check if menu exists
if ( $menu_items = wp_get_nav_menu_items( 'menu' ) ) {
   
   // Loop over menu items
   foreach ( $menu_items as $menu_item ) {

      // Compare menu item url with server request uri path
      $current = ( $_SERVER['REQUEST_URI'] == parse_url( $menu_item->url, PHP_URL_PATH ) ) ? 'current' : '';

      // Print menu item
      echo '<li class="' . $current . '"><a href="' . $menu_item->url . '">' . $menu_item->title . '</a></li>';
   }
}

I'm Robbert Vermeulen. I document everything I learn and help thousands of people with coding WordPress. My site has no ads or sponsors. If you enjoy my content, please consider supporting what I do.

Comments

  • Robbert Vermeulen

    August 8, 2021 at 11:04 am

    Thank you! Glad I could help :)

    Reply
  • John Smith

    January 1, 2021 at 2:03 pm

    Awesome Post.
    Really I Like It.

    Reply
  • Robbert Vermeulen

    April 4, 2020 at 3:54 pm

    Awesome you made it work! Keep in mind always to check first whether $menu_items->classes in an array before you use it in implode(). Else you will get an error. So maybe something like this $classes = ! empty( $menu_item->classes ) ? $menu_item->classes : ''; Good luck!

    Reply
  • Karen

    April 4, 2020 at 1:10 pm

    Thanks Robbert, its cool, i use

    $classes = $menu_item->classes[0]; — it's work

    but have alternative solution

    implode( ' ', $menu_item->classes )

    Reply
  • Robbert Vermeulen

    April 4, 2020 at 1:45 pm

    Hi Karen, you know that the classes property returns an array, right? What does var_dump( $menu_item->classes ); return for you?

    Reply
  • Karen

    April 4, 2020 at 11:56 am

    Hi Robert please tell me how do I get the classes that I specified in the admin panel for menu items? $classes = $menu_item->classes; this doesn't work

    Reply
  • Robbert Vermeulen

    July 7, 2019 at 3:26 pm

    Great to hear Adbul. Good luck!

    Reply
  • Abdul

    June 6, 2019 at 7:42 pm

    Awesome Thanks very much it works for me!

    Reply

Leave a reply

Feel free to ask questions or make comments.