I have a menu defined in WP Admin that looks like this:
I want to be able to display all the child links on the sidebar whenever I am at a parent page. For example, if the user is on my “About Us” page, I want a list of the 4 links highlighted in green to appear on the sidebar.
I looked at the documentation for wp_nav_menu() and it doesn’t appear to have any built-in way to specify a particular node of a given menu to use as the starting point when generating the links.
I created a solution for a similar situation which relied on the relationships created by the page parent, but I am looking for one which uses the menu system specifically. Any help would be appreciated.
This was still on my mind so I revisited it and put together this solution, that does not rely on context that much:
Usage
@goldenapples: Your Walker Class does not work. But the idea is really good. I created a walker based on your idea:
Now you can use:
The output is a list containing the current root element and it’s children (not their children). Def: Root element := The top level menu item that corresponds to the current page or is parent of a current page or a parent of a parent …
This does not exactly answer the original question but almost, since there is still the top level item. This is fine for me, because I want the top level element as a headline of the sidebar. If you want to get rid of this, you might have to override display_element or use a HTML-Parser.
Hi @jessegavin:
Nav Menus are stored in a combination of custom post types and custom taxonomies. Each menu is stored as a Term (i.e. “About Menu”, found in
wp_terms
) of a Custom Taxonomy (i.e.nav_menu
, found inwp_term_taxonomy
.)Each Nav Menu Item is stored as a post of
post_type=='nav_menu_item'
(i.e. “About the Firm”, found inwp_posts
) with it’s attributes stored as post meta (inwp_postmeta
) using ameta_key
prefix of_menu_item_*
where_menu_item_menu_item_parent
is the ID of your menu item’s parent Nav Menu item post.The relationship between menus and menu items is stored in
wp_term_relationships
whereobject_id
relates to the$post->ID
for the Nav Menu Item and the$term_relationships->term_taxonomy_id
relates to the menu defined collectively inwp_term_taxonomy
andwp_terms
.I’m pretty sure it would be possible to hook both
'wp_update_nav_menu'
and'wp_update_nav_menu_item'
to create actual menus inwp_terms
and a parallel set of relations inwp_term_taxonomy
andwp_term_relationships
where every Nav Menu Item that has sub-Nav Menu items also becomes it’s own Nav Menu.You’d also want to hook
'wp_get_nav_menus'
(which I suggested be added to WP 3.0 based on some similar work I was doing a few months ago) to ensure that your generated Nav Menus are not displayed for manipulation by the user in the admin, otherwise they’d get out of sync really fast and then you’d have a data nightmare on your hand.Sounds like a fun and useful project, but it is a little bit more code and testing than I can afford to tackle right now in part because anything that synchronizes data tends to be a PITA when it comes to ironing out all the bugs (and because paying clients are pressing me to get things done. 🙂 But armed with the above info I’m pretty a motivated WordPress plugin developer could code it if they wanted to.
Of course you do realize now if you do code it you are obligated to post it back here so we can all benefit from your largesse! 🙂
This is a walker extension which should do what you’re looking for:
Based loosely on mfields’ code I referenced in my comment earlier. All it does is check when walking the menu to see whether the current element is (1) the current menu item, or (2) an ancestor of the current menu item, and expands the subtree below it only if either of those conditions is true. Hope this works for you.
To use it, just add a “walker” argument when you call the menu, ie:
Update: I made this into a plugin. Download here.
I needed to solve this myself and eventually wound up writing a filter on the results of the menu lookup. It lets you use
wp_nav_menu
as normal, but choose a sub-section of the menu based on the title of the parent element. Add asubmenu
parameter to the menu like so:You can even go several levels deep by putting slashes in:
Or if you prefer with an array:
It uses a slug version of the title, which should make it forgiving of things like capitals and punctuation.
I put together the following class for myself. It will find the top nav parent of the current page, or you can give it a target top nav ID in the walker constructor.
Nav call:
@davidn @hakre
Hi, i have an ugly solution without an HTML-Parser or overriding display_element.
The nav menu output includes lots of classes for current item, current item ancestor, etc. In some situations, I have been able to do what you want to do by letting the entire nav tree output, and then using css to pare it down to only children of the current page, etc.
I made a modified walker that should help! Not perfect – it leaves a few empty elements, but it does the trick. The modification is basically those $current_branch bits.
Hope it helps someone!
}
Check out the code in my plugin or use it for your purpose 😉
This plugin adds enhanced “Navigation Menu” widget. It offers many options which could be set to customize the output of the custom menu through the widget.
Features include:
sub-items”.
selected item (option to include the parent item).
http://wordpress.org/extend/plugins/advanced-menu-widget/
The accepted answer acknowledges it requires input and isn’t based on context. Here’s a version that supports being given context, or can use WordPress’s built-in
current-x
classes to determine context:And usage:
Or…