有趣的是,几个月前我遇到了同样的难题。。。
我发现Wordpress对菜单项应用了各种CSS类以区分当前项及其祖先,但却完全忽略了子菜单及其与当前项的关系,这很奇怪。我想要一个.current-sub
CSS类,以便我可以隐藏所有内容.sub-menu
s除外.current-sub
s
理论经过大量的研究和深入研究,我最终采用的解决方案是the Walker_Nav_Menu
class 并在两个不同的点修改其行为,以获得我的想象.current-sub
CSS类:
处理菜单项时(请参见Walker_Nav_Menu->start_el()
), 检查Wordpress分配给菜单项的类,以确定它是否对应于当前页面或是menu ancestor 当前页的处理新菜单级别时(也称为“子菜单”;请参阅Walker_Nav_Menu->start_lvl()
), 如果先前处理的菜单项是当前菜单项或其祖先,请将新类应用于子菜单元素,以便将其区分为当前子菜单
Aside
请注意,我鼓起了勇气
menu ancestor 在上面在我的情况下,事实证明我实际上并不关心帖子、页面或类别的层次结构或彼此之间的关系(即,B页是否是a页的子页无关紧要)。我唯一需要担心的是它们对应的层次结构
menu-item
s。
在Walker实现之后,我只需要在模板文件中重新调用wp_nav_menu()
以我的新菜单行者的一个实例作为参数。
为了方便和简洁,我在一个过程式插件中提供了我的实现。大部分代码与本机代码相同Walker_Nav_Menu
- 我的评论表示我的补充。
//Register a new theme location for a custom menu
function after_setup_theme_97226() {
register_nav_menu( \'menu-97226\', \'Primary Navigation (uses Menu_Walker_97226)\' );
}
add_action( \'after_setup_theme\', \'after_setup_theme_97226\' );
//Queue up CSS modifications
function enqueue_styles_97226() {
wp_enqueue_style( \'style-97226\', plugins_url(\'style.css\', __FILE__) );
}
add_action( \'wp_enqueue_scripts\', \'enqueue_styles_97226\' );
//Now walk it out.
class Menu_Walker_97226 extends Walker_Nav_Menu {
const CURRENT_SUBMENU_CLASS = \'current-sub\'; //The CSS class to apply to the active submenu
var $is_current_submenu = FALSE; //Whether or not the next sub-menu to be processed is related to the current-menu-item.
function start_lvl( &$output, $depth = 0, $args = array() ) {
$indent = ( $depth ) ? str_repeat( "\\t", $depth ) : \'\';
//If we\'ve begun processing an "active" submenu, add a class to indicate as much.
$current_sub_class = ( $this->is_current_submenu ) ? Menu_Walker_97226::CURRENT_SUBMENU_CLASS : \'\';
//Add the new sub-menu ul element to the markup. Always give sub-menus the standard Wordpress "sub-menu" class.
$output .= "\\n$indent<ul class=\\"sub-menu $current_sub_class\\">\\n";
//We\'ve now processed the sub-menu; reset the flag
$this->is_current_submenu = FALSE;
}
function start_el( &$output, $item, $depth = 0, $args = array() ) {
//Reset the flag such that "active" menu-items without sub-menus don\'t pass their "current" status on to the sub-menus of their siblings
$this->is_current_submenu = FALSE;
$indent = ( $depth ) ? str_repeat( "\\t", $depth ) : \'\';
$class_names = $value = \'\';
$classes = empty( $item->classes ) ? array() : (array) $item->classes;
$classes[] = \'menu-item-\' . $item->ID;
$class_names = join( \' \', apply_filters( \'nav_menu_css_class\', array_filter( $classes ), $item, $args ) );
$class_names = $class_names ? \' class="\' . esc_attr( $class_names ) . \'"\' : \'\';
//Check to see if this element is "current" or a menu ancestor of "current" so that the "current" status may be passed on to any immediate sub-menu of the item.
//You should add or remove conditions here in order to fit your application.
//Also see "Final Notes" section below regarding performance
if (strpos($class_names, \'current-menu-item\')
|| strpos($class_names, \'current-menu-parent\')
|| strpos($class_names, \'current-menu-ancestor\')
|| strpos($class_names, \'current_page_parent\'))
$this->is_current_submenu = TRUE;
$id = apply_filters( \'nav_menu_item_id\', \'menu-item-\'. $item->ID, $item, $args );
$id = $id ? \' id="\' . esc_attr( $id ) . \'"\' : \'\';
$output .= $indent . \'<li\' . $id . $value . $class_names .\'>\';
$attributes = ! empty( $item->attr_title ) ? \' title="\' . esc_attr( $item->attr_title ) .\'"\' : \'\';
$attributes .= ! empty( $item->target ) ? \' target="\' . esc_attr( $item->target ) .\'"\' : \'\';
$attributes .= ! empty( $item->xfn ) ? \' rel="\' . esc_attr( $item->xfn ) .\'"\' : \'\';
$attributes .= ! empty( $item->url ) ? \' href="\' . esc_attr( $item->url ) .\'"\' : \'\';
$item_output = $args->before;
$item_output .= \'<a\'. $attributes .\'>\';
$item_output .= $args->link_before . apply_filters( \'the_title\', $item->title, $item->ID ) . $args->link_after;
$item_output .= \'</a>\';
$item_output .= $args->after;
$output .= apply_filters( \'walker_nav_menu_start_el\', $item_output, $item, $depth, $args );
}
}
引用的
style.css
文件如下:
ul.sub-menu {
display:none;
}
ul.current-sub {
display:block;
}
最后,致电
wp_nav_menu()
在要显示菜单以使用新Walker的模板文件中(有关其他参数,请参阅文档):
wp_nav_menu( array(
\'theme_location\' => \'menu-97226\',
\'walker\' => new Menu_Walker_97226()
) );
我还没有运行基准测试,但使用
in_array()
在
$classes
数组已联接,而不是使用
strpos()
事后致电。也可以使用
array_flip()
并随后使用
isset( $classes[ $class_name ] )
, 虽然我怀疑翻转会破坏使用
isset()
.在我的实施过程中,有一部分很大程度上受到了一篇博客文章的启发,而在这段时间里,我一直没有注意到这篇博客文章。如果我设法找到它,我将返回链接它should 将显示。。。我的术语有点模糊,目前我的头脑混乱——我会稍后再回来整理;)这可能不是您所寻求的确切解决方案(很可能存在更好的解决方案),但我希望这足以让您走上正确的道路!