如何从自定义Walker_Nav_Menu中删除项目

时间:2020-04-09 作者:MarvynH

我在wordpress+woocommerce网站上有一个自定义菜单,使用Walker\\u Nav\\u菜单类。从站点隐藏帖子(产品)时,这些帖子和类别仍包含在自定义菜单中。我想知道如何从此菜单中删除特定的产品帖子,例如帖子ID=6927,或者如何从该菜单中删除类别(以及其中的产品),例如类别ID=41。我要隐藏的类别在此图像中为“范围结束”:

screengrab of custom menu

在过去的两天里,我尝试了许多解决方案,但都没有成功:

(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 ); 
以及上述的不同变体。

我不确定我是否完全偏离了轨道,但我想更新文件模板部件/模块/模块类别菜单。php排除该类别可能有效,以下是该文件的内容:

<?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; 
?>
非常感谢您的帮助。

EDIT这是函数中的Walker\\u Nav\\u菜单类。php文件:

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$indent<div class=\'collapse\' id=\'submenu$thisItem->ID\' aria-expanded=\'false\'><ul id=\'submenu-$thisItem->ID\' class=\'flex-column nav sub-nav\'>\\n";
    }

}

2 个回复
SO网友:simongcc

我仍然不知道你怎么称呼菜单,或者你为菜单提供了多少美元。但可以给你一些方法来解决这个问题。

第一个测试:返回一个空数组,如果菜单变为空,则过滤器正在运行,

如果没有,那么您的筛选器没有运行,需要找到其他方法

function wpse31748_exclude_menu_items( $items, $menu, $args ) {
    return [];
}
add_filter( \'wp_get_nav_menu_items\', \'wpse31748_exclude_menu_items\', null, 3 ); 
假设过滤器正在运行,那么您的测试逻辑可能有问题

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 ); 

SO网友:MarvynH

我通过编辑$cat\\u args数组来排除我不想在任何菜单中显示的类别ID(在下面的示例中,34是类别ID),解决了这个问题-在我的示例中,文件位于“modules”文件夹中:

<?php
$orderby = \'date\';
$order = \'desc\';
$hide_empty = true ;
$cat_args = array(
  \'orderby\'    => $orderby,
  \'order\'      => $order,
  \'hide_empty\' => $hide_empty,
  \'exclude\' => \'34\',
);
类别已从菜单中删除,但仍可以通过直接链接访问和链接特定帖子。