自定义Nav Walker显示当前菜单项的子级,或没有子级的同级项


14

我一直在闲逛/搜索数小时,但仍然无法正常工作,所以我终于屈服了,寻求帮助。

我正在尝试编写一个仅显示当前页面子级的自定义行者,或者如果没有子级显示页面同级。

例如,采用以下菜单树:

  • 1.0
    • 1.2.0
      • 1.3.0
      • 1.3.1
      • 1.3.2
    • 1.2.1
    • 1.2.2
  • 2.0

假设我在当前页面1.2.0上。在此页面上,我要显示其子级(1.3.0、1.3.1、1.3.2)

但是,如果我在1.2.2页上,由于它没有任何子级,它应该显示其当前级别的同级,因此应该显示给我(1.2.0、1.2.1、1.2.2)。


4
请将您的解决方案移至答案,以便其他人更清楚,问题也不会困扰着未解决的站点。
2013年

@Rarst说什么!我几乎错过了您想出解决方案的机会。
克里斯·克里乔

死灵的答案。大约两年前,我在SO上或多或少地问了同样的问题,并给出了很好的答案。stackoverflow.com/questions/5826609/…–
Stoosh

将问题内的答案移到单独的答案。OP:请在那里继续。
kaiser

Answers:


4

这是我用来仅显示当前菜单项的子项的助行器。或者菜单项的兄弟姐妹(如果没有自己的子项)。

整个课堂上都有评论解释每个部分

<?php

class SH_Child_Only_Walker extends Walker_Nav_Menu {

private $ID;
private $depth;
private $classes = array();
private $child_count = 0;
private $have_current = false;


// Don't start the top level
function start_lvl(&$output, $depth=0, $args=array()) {

    if( 0 == $depth || $this->depth != $depth )
        return;

    parent::start_lvl($output, $depth,$args);
}

// Don't end the top level
function end_lvl(&$output, $depth=0, $args=array()) {
    if( 0 == $depth || $this->depth != $depth )
        return;

    parent::end_lvl($output, $depth,$args);
}

// Don't print top-level elements
function start_el(&$output, $item, $depth=0, $args=array()) {

    $is_current = in_array('current-menu-item', $this->classes);

    if( 0 == $depth || ! $is_current )
        return;

    parent::start_el($output, $item, $depth, $args);
}

function end_el(&$output, $item, $depth=0, $args=array()) {
    if( 0 == $depth )
        return;

    parent::end_el($output, $item, $depth, $args);
}

// Only follow down one branch
function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ) {

    // Check if element is in the current tree to display
    $current_element_markers = array( 'current-menu-item', 'current-menu-parent', 'current-menu-ancestor' );
    $this->classes = array_intersect( $current_element_markers, $element->classes );

    // If element has a 'current' class, it is an ancestor of the current element
    $ancestor_of_current = !empty($this->classes);

    // check if the element is the actual page element we are on.
    $is_current = in_array('current-menu-item', $this->classes);

    // if it is the current element
    if($is_current) {

        // set the count / ID / and depth to use in the other functions.
        $this->child_count = ( isset($children_elements[$element->ID]) ) ? count($children_elements[$element->ID]) : 0;
        $this->ID = $element->ID;
        $this->depth = $depth;
        $this->have_current = true;

        if($this->child_count > 0) {

            // if there are children loop through them and display the kids.
            foreach( $children_elements[$element->ID] as $child ) {
                parent::display_element( $child, $children_elements, $max_depth, $depth, $args, $output );
            }

        } else {
            // no children so loop through kids of parent item.
            foreach( $children_elements[$element->menu_item_parent] as $child ) {
                parent::display_element( $child, $children_elements, $max_depth, $depth, $args, $output );
            }

        }
    }

    // if depth is zero and not in current tree go to the next element
    if ( 0 == $depth && !$ancestor_of_current)
        return;

    // if we aren't on the current element proceed as normal
    if(! $this->have_current )
        parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
}
}

像在wp_nav_menu上将其与任何其他自定义助步器一样进行附加

<?php
wp_nav_menu( array(
    'menu' => 'primary-menu'
    ,'container' => 'nav'
    ,'container_class' => 'subpages'
    ,'depth' => 0
    ,'walker' => new SH_Child_Only_Walker()
 ));
?>

我想指出@Stoosh的评论指向此处。stackoverflow.com/questions/5826609/…,因为这是另一个不错的解决方案
jchamb

0

我也有类似的经历。您可能需要考虑将页面逻辑移出沃克。基本上,将当前页面层次结构编译为一个对象。然后在wp_nav_menu函数中使用'exclude'参数。现在,排除的页面将取决于当前页面是否有子页面。如果没有孩子陪伴兄弟;如果孩子&&这些孩子在行尾显示兄弟姐妹;如果存在子&&和孙子,则排除兄弟并显示子孙。


这是什么exclude参数,你提到?我正在查看文档,但看不到任何参考。
克里斯·克里斯乔

1
我很抱歉我误会了。您是正确的,没有“排除”参数。我打算使用“ wp_list_pages”功能。
史蒂夫·菲舍尔

很好,没有后顾之忧。我只是想知道是否有未记录的东西,但是在后端—我以前见过这种情况。感谢您清理!我没想到要wp_list_pages()在这种情况下使用,所以这是一个有趣的想法。
克里斯·克里乔
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.