Dynamically exclude menu items from wp_nav_menu

Method 1

You can add a constructor to your custom Walker to store some additional exclusion arguments, like:

class custom_nav_walker extends Walker_Nav_Menu {
    function __construct( $exclude = null ) {
        $this->exclude = $exclude;
    }

    function skip( $item ) {
        return in_array($item->ID, (array)$this->exclude);
        // or
        return in_array($item->title, (array)$this->exclude);
        // etc.
    }

    // ...inside start_el, end_el
    if ( $this->skip( $item ) ) return;
}

Or drop the constructor and set its $exclude property before passing it in as a walker to wp_nav_menu() like so:

$my_custom_nav_walker = new custom_nav_walker;
$my_custom_nav_walker->exclude = array( ... );

Depending on what you’re excluding by, supply the correct form to the exclude.

Method 2

This is how you would go about doing this by hooking into the wp_get_nav_menu_items filter.

function wpse31748_exclude_menu_items( $items, $menu, $args ) {
    // Iterate over the items to search and destroy
    foreach ( $items as $key => $item ) {
        if ( $item->object_id == 168 ) unset( $items[$key] );
    }

    return $items;
}

add_filter( 'wp_get_nav_menu_items', 'wpse31748_exclude_menu_items', null, 3 );

Note: object_id is the object the menu points to, while ID is the menu ID, these are different.

Let me know your thoughts.

Leave a Comment