In der benutzerdefinierten Navigationsanzeige wird der aktuelle Menüpunkt Kinder oder Geschwister ohne Kinder angezeigt

14

Ich habe stundenlang rumgespielt / gesucht und kann es immer noch nicht zum Laufen bringen, also gebe ich endlich nach und bitte um Hilfe.

Ich versuche, einen benutzerdefinierten Walker zu schreiben, der nur die aktuellen untergeordneten Seiten anzeigt, oder wenn keine untergeordneten Seiten vorhanden sind, werden die Seitengeschwister angezeigt.

Nehmen Sie zum Beispiel den folgenden Menübaum:

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

Nehmen wir an, ich bin auf der aktuellen Seite 1.2.0. Auf dieser Seite möchte ich seine Kinder anzeigen (1.3.0, 1.3.1, 1.3.2)

Wenn ich mich jedoch auf der Seite 1.2.2 befinde, sollte sie, da sie keine Kinder hat, die Geschwister der aktuellen Ebene anzeigen, sodass sie mich anzeigen sollten (1.2.0, 1.2.1, 1.2.2).

jchamb
quelle
4
Bitte verschieben Sie Ihre Lösung auf eine Antwort, damit es für andere klarer wird und Fragen die Site nicht als unbeantwortet verfolgen.
Rarst
Was @Rarst gesagt hat! Fast hätte ich übersehen, dass Sie eine Lösung gefunden hätten.
Chris Krycho
Necro antworte. Ich habe SO vor ungefähr 2 Jahren mehr oder weniger dieselbe Frage mit einer sehr guten Antwort gestellt. stackoverflow.com/questions/5826609/…
Stoosh
Die Antwort in der Frage wurde verschoben, um die Antwort zu trennen. OP: Bitte folgen Sie dort.
Kaiser

Antworten:

4

Dies ist der Walker, mit dem ich nur untergeordnete Elemente des aktuellen Menüelements angezeigt habe. Oder die Menüpunkte Geschwister, wenn es keine eigenen Kinder hat.

Es gibt Kommentare in der gesamten Klasse, die jeden Abschnitt erklären

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

Bringen Sie es wie bei jedem anderen benutzerdefinierten Walker in einem wp_nav_menu an

<?php
wp_nav_menu( array(
    'menu' => 'primary-menu'
    ,'container' => 'nav'
    ,'container_class' => 'subpages'
    ,'depth' => 0
    ,'walker' => new SH_Child_Only_Walker()
 ));
?>
jchamb
quelle
Ich möchte auf @ Stooshs Kommentar hinweisen, der hier zeigt. stackoverflow.com/questions/5826609/… da dies eine weitere gute lösung ist
jchamb
0

Ich hatte eine ähnliche Erfahrung. Vielleicht möchten Sie darüber nachdenken, die Seitenlogik aus dem Walker zu verschieben. Kompilieren Sie grundsätzlich die aktuelle Seitenhierarchie als Objekt. Verwenden Sie dann den Parameter 'exclude' in der Funktion wp_nav_menu. Nun würden die ausgeschlossenen Seiten davon abhängen, ob die aktuelle Seite untergeordnete Seiten hat. Wenn keine Kinder Brüder zeigen; Wenn Kinder und diese Kinder das Ende der Reihe sind, zeige Brüder und Kinder. Wenn Kinder und Enkel vorhanden sind, schließen Sie Brüder aus und zeigen Sie Kinder und Enkel.

Steve Fischer
quelle
Auf welchen excludeParameter beziehen Sie sich? Ich schaue mir die Dokumentation an und sehe keinen Hinweis darauf.
Chris Krycho
1
Ich entschuldige mich, dass ich mich geirrt habe. Sie haben Recht, dass es keinen 'exclude'-Parameter gibt. Ich wollte die Funktion "wp_list_pages" verwenden.
Steve Fischer
Sehr gut und keine Sorge. Ich war nur neugierig, ob es etwas Undokumentiertes gab, aber im Hintergrund - ich habe das schon einmal gesehen. Vielen Dank für die Aufklärung! Ich hatte nicht daran gedacht, dies wp_list_pages()in diesem Zusammenhang zu verwenden, das ist also eine interessante Idee.
Chris Krycho