Get the top-most parent ID from a WordPress menu easily, with a one-stop function that will grab that parent so you can do whatever you need with it.

If you’re using WordPress’ built-in menu function for your site’s hierarchy because it is easy to use, then you know that finding the top-most parent ID or crawling the general hierarchy itself isn’t that easy. In one instance I needed to access a meta value for every page beneath a parent page in a WordPress menu: there were four top-level pages and each one had sidebar meta set. Every pay beneath those four primary sections needed to inherit that meta through the WordPress menu alone. Here is the solution I made for that:

function get_menu_parent_ID($menu_name){
    if(!isset($menu_name)){
      return "No menu name provided in arguments";
    }
    $menu_slug = $menu_name;
    $locations = get_nav_menu_locations();
    $menu_id   = $locations[$menu_slug];
    $post_id        = get_the_ID();
    $menu_items     = wp_get_nav_menu_items($menu_id);
    $parent_item_id = wp_filter_object_list($menu_items,array('object_id'=>$post_id),'and','menu_item_parent');
    $parent_item_id = array_shift( $parent_item_id );
    function checkForParent($parent_item_id,$menu_items){
      $parent_post_id = wp_filter_object_list( $menu_items, array( 'ID' => $parent_item_id ), 'and', 'object_id' );
      $parent_item_id = wp_filter_object_list($menu_items,array('ID'=>$parent_item_id),'and','menu_item_parent');
      $parent_item_id = array_shift( $parent_item_id );
      if($parent_item_id=="0"){
        $parent_post_id = array_shift($parent_post_id);
        return $parent_post_id;
      }else{
        return checkForParent($parent_item_id,$menu_items);
      }
    }
    if(!empty($parent_item_id)){
      return checkForParent($parent_item_id,$menu_items);
    }else{
      return $post_id;
    }
  }

If you’re a developer and you’re working on something complicated using the WordPress menu and you require some sort of top-level inheritance, just include that function in functions.php and fire it as so:

$parentID = get_menu_parent_ID('main_nav');

That will then grab the menu ID of the menu name that you provided, check if your current page exists in the menu, check if that menu has a parent, check if that menu item has a parent and if it does the function will rerun, otherwise it will return the ID of that menu item it found. It’s recursive function that will get you where you need and save you some time from learning the wp_nav_items if all you need is some inherited functions.

The function requires a menu name¬†otherwise it cannot function. If you don’t include a menu name then it will spit out a configuration error.

Download Gist here