Custom Nav walker exibe as crianças do item de menu atual ou irmãos sem filhos

13

Eu tenho andado por aí / procurando por horas e ainda não consigo fazer isso funcionar, então finalmente estou cedendo e pedindo ajuda.

Estou tentando escrever um walker personalizado que mostre apenas as páginas atuais children ou, se não houver filhos, exiba as páginas de irmãos.

Por exemplo, pegue a seguinte árvore de menu:

  • 1,0
    • 1.2.0
      • 1.3.0
      • 1.3.1
      • 1.3.2
    • 1.2.1
    • 1.2.2
  • 2.0

Vamos supor que eu esteja na página atual 1.2.0. Nesta página eu quero mostrar seus filhos (1.3.0, 1.3.1, 1.3.2)

no entanto, se eu estiver na página 1.2.2, uma vez que ele não tem filhos, ele deve mostrar seus irmãos atuais, então ele deve mostrar-me (1.2.0, 1.2.1, 1.2.2 ).

    
por jchamb 27.01.2013 / 22:33

2 respostas

4

Este é o walker que usei para exibir apenas os filhos do item de menu atual. Ou os itens do menu irmãos, se ele não tiver filhos.

Há comentários durante a aula explicando cada seção

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

Anexe como você faria com qualquer outro walker personalizado em um wp_nav_menu

<?php
wp_nav_menu( array(
    'menu' => 'primary-menu'
    ,'container' => 'nav'
    ,'container_class' => 'subpages'
    ,'depth' => 0
    ,'walker' => new SH_Child_Only_Walker()
 ));
?>
    
por jchamb 11.11.2013 / 22:20
0

Eu tive uma experiência semelhante. Você pode querer pensar em mover a lógica das páginas para fora do andador. Basicamente, compile a hierarquia de páginas atual como um objeto. Em seguida, use o parâmetro 'exclude' na função wp_nav_menu. Agora, as páginas excluídas dependerão se a página atual tiver filhos. Se nenhuma criança mostrar irmãos; if children & & essas crianças são o fim da linha, mostram irmãos e filhos; if children & & e netos existem excluem irmãos e mostram filhos e netos.

    
por Steve Fischer 21.02.2013 / 13:01