The menu builder in WordPress is great, however quite often I find myself needing to create a secondary menu on pages, containing just a subset of the menu. In my case the rules are simple: when viewing a top level page we want to list all child pages nested beneath it. When viewing a second level page, we want to list all sibling pages nested under the same parent. We could just use wp_list_pages and filter by a parent, but it won’t match the structure designed in the menu builder.

Surprisingly there’s little information or working solutions to this problem, so I’ve put together the following code which does exactly what we want.

To give you an idea of how it works with the default options, imagine you have a menu like this:

– A
– – B
– – C
– D

If you’re on page A, you’ll see B and C in the menu (A is a top level page, so it shows children). If you’re on B or C, again, you’ll see B and C (B and C are second level pages, so it shows siblings).

A big thanks goes out to Thomas Dexter who kindly pointed out a way to use wp_nav_menu, which adds the correct wp classes and allows us to use custom walkers and the like. Using his code and the hook provided by mac joost on Stack Overflow, I created a filter that works based purely on the menu structure (irrelevant of page structure). So all you need to do is drop this in your functions.php file (remember to remove the opening <?php tag first).