Custom 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
โปรดย้ายโซลูชันของคุณไปยังคำตอบเพื่อให้ชัดเจนยิ่งขึ้นสำหรับผู้อื่นและคำถามไม่ได้หลอกหลอนไซต์ดังกล่าว
Rarst

@Rarst พูดอะไร! ฉันเกือบพลาดว่าคุณคิดวิธีแก้ปัญหา
Chris Krycho

คำตอบ Necro ฉันถามคำถามเดียวกันเกี่ยวกับ SO มากขึ้นหรือน้อยลงเมื่อประมาณ 2 ปีที่แล้วพร้อมคำตอบที่ดีมาก stackoverflow.com/questions/5826609/…
Stoosh

ย้ายคำตอบภายในคำถามเพื่อแยกคำตอบ OP: โปรดติดตามที่นั่น
ไกเซอร์

คำตอบ:


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พารามิเตอร์นี้ที่คุณอ้างถึงคืออะไร ฉันกำลังดูเอกสารและไม่เห็นการอ้างอิงใด ๆ
Chris Krycho

1
ฉันขอโทษที่ฉันเข้าใจผิด คุณถูกต้องว่าไม่มีพารามิเตอร์ 'ยกเว้น' ฉันตั้งใจจะใช้ฟังก์ชั่น "wp_list_pages"
Steve Fischer

ดีมากและไม่ต้องกังวล ฉันแค่อยากรู้อยากเห็นหากมีสิ่งที่ไม่มีเอกสาร แต่ในส่วนท้าย - ฉันได้เห็นสิ่งนั้นเกิดขึ้นก่อนหน้านี้ ขอบคุณที่ล้างมัน! ฉันไม่ได้คิดที่จะใช้wp_list_pages()ในบริบทนี้ดังนั้นจึงเป็นแนวคิดที่น่าสนใจ
Chris Krycho
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.