How to remove an item from a custom Walker_Nav_Menu

I have a custom menu on a wordpress + woocommerce site using the Walker_Nav_Menu class. When hiding posts (products) from the site those posts and category are still included in the custom menu. I would like to know how to remove either the specific product posts from this menu, for e.g. post ID = 6927 - or to remove the category (and the products therein) from this menu, for e.g. category ID = 41.The category I want to hide is "End of range" in this image:

I have tried many solutions over the past 2 days without success:

1)

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 == 6927 ) unset( $items[$key] );
    }

    return $items;
}

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

and different variations of above.

I'm not sure if I'm completely off track but I thought updating the file template-parts/modules/module-category-menu.php to exclude the category may work, here is the contents of that file:

?php
$orderby = 'date';
$order = 'desc';
$hide_empty = true ;
$cat_args = array(
  'orderby'    = $orderby,
  'order'      = $order,
  'hide_empty' = $hide_empty,

);

$product_categories = get_terms( 'product_cat', $cat_args );
if( !empty($product_categories)) : 
  ?
  div class="row"
    div class="col-12 sec-menu"
      ul class=" nav nav-justified" id="sec-menu"
        ?php
        foreach ($product_categories as $key = $category):
          ?
          li class="nav-item"
            h2
            a class="nav-link collapsed top-menu" href="#cat?php echo $category-term_id; ?" data-toggle="collapse" data-target="#cat?php echo $category-term_id; ?"  
             ?php echo $category-name; ?

           /a
            /h2     
           ?php
           $args = array(
            'posts_per_page' = '-1',
            'post_type' = 'product',
            'post_status' = 'publish',
            'orderby'    = 'date',
            'order'      = 'asc',
            'tax_query' = array(
              array(
                'taxonomy'  = 'product_cat',
                'terms'     = array($category-term_id),
                'operator'   = 'IN'
              ),
            )
          );
           $products = new WP_Query($args);
           if($products-have_posts()):
             ?
             div class="collapse sub-menu" id="cat?php echo $category-term_id; ?" aria-expanded="false" data-parent="#sec-menu"
              ul class="flex-column nav"
                ?php
                while($products-have_posts()):
                  $products-the_post();
                  ?
                  li class="nav-item"
                    a class="nav-link sub-link" href="?php the_permalink();?" title="?php the_title(); ?"
                      span?php the_title(); ?/span                      
                    /a
                  /li
                  ?php
                endwhile;
                wp_reset_query();
                ?
              /ul
            /div
            ?php
          endif;
          ?
        /li
        ?php
      endforeach;
      ?
    /ul
  /div
/div
?php
endif; 
?

Any help is greatly appreciated.

EDIT Here is the Walker_Nav_Menu class from the functions.php file:

class Custom_Foundation_Nav_Menu extends Walker_Nav_Menu

 {


    private $curItem;

    function display_element($element, $children_elements, $max_depth, $depth = 0, $args, $output)
    {

        $element-hasChildren = isset($children_elements[$element-ID])  !empty($children_elements[$element-ID]);
        return parent::display_element($element, $children_elements, $max_depth, $depth, $args, $output);

    }

    function start_el($output, $item, $depth = 0, $args = array(), $id = 0)
    {

        global $wp_query;

        $new_class = array();

        $this-curItem = $item;

        $indent = ($depth) ? str_repeat("\t", $depth) : '';

        $class_names = $value = '';

        $classes = empty($item-classes) ? array() : (array) $item-classes;
        $new_class[] = 'nav-item';
        if (in_array('current-menu-item', $classes) || in_array('current-menu-ancestor', $classes)) {
            $new_class[] = 'active';
        }
        if ($item-hasChildren) {
            $add_sub_class = 'nav-link collapsed';
        } else {
            $add_sub_class = 'nav-link';
        }

        if ($depth  0) {
            $add_sub_class .= ' sub-link ';
        }



        $new_class = implode(' ', $new_class);
        // echo $new_class;
        $class_names = join(' ', apply_filters('nav_menu_css_class', array_filter($classes), $item));
        $class_names = ' class="' . $new_class . ' ' . $class_names . '"';
        $class_names = trim($class_names);


        $output .= $indent . 'li id="menu-item-' . $item-ID . '" ' . $value . $class_names . '';
        $attributes = !empty($item-attr_title) ? ' title="' . esc_attr($item-attr_title) . '" ' : '';
        if ($item-hasChildren  !is_page(6927)) {
            $attributes .= ' href="#submenu' . $item-ID . '" ';
            $attributes .= ' data-toggle="collapse" ';
            $attributes .= ' data-target="#submenu' . $item-ID . '" ';
        } else {
            $attributes .= !empty($item-url) ? ' href="' . esc_attr($item-url) . '" ' : '';
        }
        $attributes .= !empty($add_sub_class) ? ' class="' . $add_sub_class . '" ' : '';

        $item_output = $args-before;
        $item_output .= 'a' . $attributes . ' span data-hover="' . $args-link_before . apply_filters('the_title', $item-title, $item-ID) . '"';

        $item_output .= $args-link_before . apply_filters('the_title', $item-title, $item-ID);
        $item_output .= '/span/a';
        $item_output .= $args-after;

        $output .= apply_filters('walker_nav_menu_start_el', $item_output, $item, $depth, $args);
    }

    function start_lvl($output, $depth = 0, $args = array())

    {
        global $wp_query;

        $thisItem = $this-curItem;
        $indent = str_repeat("\t", $depth);
        $output .= "\n$indentdiv class='collapse' id='submenu$thisItem-ID' aria-expanded='false'ul id='submenu-$thisItem-ID' class='flex-column nav sub-nav'\n";
    }

}

Topic exclude walker categories menus Wordpress

Category Web


I've resolved this by editing the $cat_args array to exclude the category IDs I don't want shown in any menu (in below e.g. 34 is the category ID) - the file in my case was in a 'modules' folder:

<?php
$orderby = 'date';
$order = 'desc';
$hide_empty = true ;
$cat_args = array(
  'orderby'    => $orderby,
  'order'      => $order,
  'hide_empty' => $hide_empty,
  'exclude' => '34',
);

Category is removed from the menu but the specific posts can still be accessed and linked to with direct linking.


I am still not sure how you call the menu or what $args you supply for the menu. But could suggest you some way to figure it out.

first test: return an empty array, if menu becomes empty, the filter is running,

if not, then your filter is not running and need to find another way

function wpse31748_exclude_menu_items( $items, $menu, $args ) {
    return [];
}
add_filter( 'wp_get_nav_menu_items', 'wpse31748_exclude_menu_items', null, 3 ); 

assume the filter is running, then probably your test logic have problem

function wpse31748_exclude_menu_items( $items, $menu, $args ) {

    // Iterate over the items to search and destroy
    $found_key = null;
    foreach ( $items as $key => $item ) {
        if ( $item->object_id == 6927 ) {
          // unset( $items[$key] ); // unset a iterating array is not a good idea and may lead to bug sometimes
          $found_key = $key; // handle it later.
        }
    }

    var_dump($found_key); // make sure you find something

    var_dump($items); // to compare before and after removal if it found something
    unset( $items[$found_key] );
    var_dump($items);

    return $items;
}

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

About

Geeks Mental is a community that publishes articles and tutorials about Web, Android, Data Science, new techniques and Linux security.