There are plenty of tutorials and code snippets online describing how to show the active page’s children (or if on one of those children, the active page’s siblings) as a sub-menu in WordPress. Usually something like this:
[php]
<?php
$ref_post = empty($post->post_parent) ? $post->ID : $post->post_parent;
$children = wp_list_pages(‘title_li=&child_of=’.$ref_post.’&echo=0′);
if ($children) {
echo “<ul>$children</ul>”;
}
?>
[/php]
This is fine and dandy when your menus and your page hierarchy line up. But how do you achieve the same thing if you’re using a custom menu, from the Appearance -> Menus area in the site administration, and your page child-parent relationships are handled separately? There’s a little bit more to it. This snippet will grab the top level page’s submenu items and display them in an unordered list, useful for generating submenus in some scenarios.
[php]
<?php
$section_id = empty( $post->ancestors ) ? $post->ID : end( $post->ancestors );
$locations = get_nav_menu_locations();
$menu = wp_get_nav_menu_object( $locations[ ‘primary’ ] ); // ‘primary’ is our nav menu’s name
$menu_items = wp_get_nav_menu_items( $menu->term_id, array( ‘post_parent’ => $section_id ) );
if( !empty( $menu_items ) ) {
echo ‘<ul class=”section-submenu”>’;
foreach( $menu_items as $menu_item ) {
echo ‘<li><a href=”‘ . $menu_item->url . ‘”>’ . $menu_item->title . ‘</a></li>’;
}
echo ‘</ul>’;
}
?>
[/php]
Stick that code in a function and go make yourself a bag of microwave popcorn. You’ve earned it. Now get back here and step through this line by line.
A little shorthand since it’s Friday, if there are no ancestors use the current post, otherwise use the last ancestor.
[php] $section_id = empty( $post->ancestors ) ? $post->ID : end( $post->ancestors );[/php]
Get the custom nav menus set in WordPress
[php] $locations = get_nav_menu_locations();[/php]
You might need to change ‘primary’ if you are copying and pasting this, that’s just what we used in this theme
[php] $menu = wp_get_nav_menu_object( $locations[ ‘primary’ ] ); // ‘primary’ is our nav menu’s name[/php]
Get the submenu items of the section we identified earlier
[php] $menu_items = wp_get_nav_menu_items( $menu->term_id, array( ‘post_parent’ => $section_id ) );[/php]
Now, if there are any menu items to list, spit them out in an unordered list.
[php] if( !empty( $menu_items ) ) {
echo ‘<ul class=”section-submenu”>’;
foreach( $menu_items as $menu_item ) {
echo ‘<li><a href=”‘ . $menu_item->url . ‘”>’ . $menu_item->title . ‘</a></li>’;
}
echo ‘</ul>’;
}[/php]
Now go get a clean rag and wipe down your keyboard, you got butter all over it. See you next year, folks.