如何在不依赖自定义Walker的情况下使用Walker钩子/过滤器删除子菜单?

时间:2018-02-21 作者:Gazillion

我目前构建了一个非常简单的工具来创建一个超大菜单。我在“外观”>“菜单”部分的菜单项中添加了一个复选框,然后是一个下拉列表,其中包含主题中的模板文件。

以下是我当前函数的工作方式(或不工作):

function mega\\u menu\\u start\\u el($输出,$项目,$深度,$参数,$id=0){

$is_mega = FALSE;
$in_mega = FALSE;

if( $depth > 0 ) {

    $parent_ID = get_post_meta( $item->ID, \'_menu_item_menu_item_parent\', TRUE );

    if( $parent_ID ) {
        while( $parent_ID ) { //get the root parent
            $current_ID = $parent_ID; //on the late iteration, current_ID will hold the root parent
            $parent_ID = get_post_meta( $parent_ID, \'_menu_item_menu_item_parent\', TRUE );
        }
        $in_mega = get_post_meta( $current_ID, \'menu-item-make-mega\', TRUE );
    }
}
else {
    $is_mega = get_post_meta( $item->ID, \'menu-item-make-mega\', TRUE );
}

if( $in_mega ) {
    return;
}
elseif( !$is_mega ) {
    return $output;
}
else {      
    $template = get_post_meta( $item->ID, \'menu-item-mega-tpl\', TRUE );

    if( file_exists( $template ) ) {

        $mega_menu = \'%s<div id="mega-menu-%s" class="mega-menu mega-menu-%s">%s</div>\';

        ob_start();             
        include( $template );
        $mega_menu_output = ob_get_clean();
        return sprintf( $mega_menu,
                $output,
                $item->ID,
                basename( str_replace( \'.\', \'-\', $template ) ),
                $mega_menu_output
            );
    }
}
}

现在这种方式可以工作了,因为如果菜单项不是大菜单,它只返回默认生成的输出,如果是大菜单,它会清除输出,如果是大菜单,它会加载模板并将其添加到链接旁边,就像子菜单一样。

问题是,由于我似乎找不到默认子菜单的生成位置,我仍然有空的子菜单标记(因为清除输出只会清除锚定标记以及在“before”和“after”参数中设置的任何内容):

<ul class="sub-menu">
    <li id="menu-item-105" class="menu-item menu-item-type-post_type menu-item-object-product menu-item-105"></li>
    <li id="menu-item-106" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-106"></li>
    <li id="menu-item-107" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-107"></li>
</ul>
所以基本上我想挂到一个比这更高的级别,检查我是否在一个超大菜单中,如果是这样的话,那么就把它炸了。

我已经为此绞尽脑汁了一段时间,所以任何提示都将不胜感激。

非常感谢。

编辑:好的,所以我认为使用过滤器是不可能的,因为没有用于start\\u lvl的过滤器(只有start\\u el)。这意味着我必须构建一个自定义助行器来实现这一点,我希望避免与可能已经使用自定义助行器作为菜单的主题发生冲突。

我能够通过扩展默认Nav\\u Menu\\u walker类的walker实现我想要的。对于任何好奇的人,我修改了上面的函数,以便将其添加到$output 变量,而不是返回任何内容。

我还添加了一个私有变量来保存我们当前是否在超级菜单中,因为walk方法将从根父级遍历树,然后一直遍历到它的子级。这意味着我可以设置$this->_in_mega 同时作为$is_mega. 然后,当我在的时候start_lvl()end_lvl() 我打电话parent::start_lvl()parent::end_lvl() 如果我们目前不在超级菜单中。

我将保留我的问题,因为我希望有一个不同的解决方案(有人可以提供),但现在,这对我来说已经足够好了。

1 个回复
SO网友:Atif Aqeel

隐藏子菜单的最佳且简单的方法是使用css

.sub-menu {
   display: none !important;
}
或者可以使用“深度”=>1

   `wp_nav_menu( array( \'menu_id\'=>\'nav\', \'theme_location\'=>\'header-menu\' , \'depth\' => 1) );
或者创建一个函数,为特定菜单设置“深度”=>1。将此代码放在主题函数中。php

  add_filter( \'wp_nav_menu_args\', \'remove_my_header_dropdown\', 1, 1 );
  function remove_my_header_dropdown( $args )
   {
    //lookup theme_location ie: top-menu
    if ( isset( $args[\'theme_location\'] ) && \'top-menu\' == 
    $args[\'theme_location\'] ) {
    $args[\'depth\'] = 1; //levels of the hierarchy are to be included
    }

    return $args;
}
“希望这对你有用

结束

相关推荐

确定父菜单WP Nav Walker的最后一个子菜单

有没有办法添加一个条件来知道导航助行器的当前项是菜单的最后一个子项还是父项?| Item 1 | Item 2 | | - Item 1.1 | - Item 2.1 | | - Item 1.2 | - Item 2.2 | | - Item 1.3 |<----------------- Determine if current item is last child 例如:if ($item->last_child(of_c