Pejalan kaki Nav kustom menampilkan item menu saat ini anak-anak, atau saudara kandung pada anak-anak

14

Saya telah bermain-main / mencari selama berjam-jam dan masih tidak bisa bekerja, jadi saya akhirnya menyerah dan meminta bantuan.

Saya mencoba menulis custom walker yang hanya menampilkan halaman anak saat ini, atau jika tidak ada anak yang menampilkan halaman saudara.

Misalnya, ambil susunan menu berikut:

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

Mari kita asumsikan bahwa saya ada di halaman saat ini 1.2.0. Di halaman ini saya ingin menampilkannya anak-anak (1.3.0, 1.3.1, 1.3.2)

namun, jika saya ada di halaman 1.2.2, karena tidak memiliki anak, ia harus menampilkan saudara kandungnya saat ini, jadi itu harus ditunjukkan kepada saya (1.2.0, 1.2.1, 1.2.2).

jchamb
sumber
4
Harap pindahkan solusi Anda ke jawaban sehingga lebih jelas bagi orang lain dan pertanyaan tidak menghantui situs sebagai tidak terjawab.
Rarst
Apa yang dikatakan @Rarst! Saya hampir ketinggalan bahwa Anda akan menemukan solusi.
Chris Krycho
Necro menjawab. Saya mengajukan kurang lebih pertanyaan yang sama pada SO sekitar 2 tahun yang lalu dengan jawaban yang sangat bagus. stackoverflow.com/questions/5826609/…
Stoosh
Memindahkan jawaban di dalam pertanyaan untuk memisahkan jawaban. OP: Silakan ikuti di sana.
kaiser

Jawaban:

4

Ini adalah alat bantu yang saya gunakan untuk menampilkan hanya anak-anak dari item menu saat ini. Atau menu item saudara kandung jika tidak memiliki anak sendiri.

Ada komentar di seluruh kelas yang menjelaskan setiap bagian

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

Lampirkan seperti yang Anda lakukan dengan walker khusus lainnya di wp_nav_menu

<?php
wp_nav_menu( array(
    'menu' => 'primary-menu'
    ,'container' => 'nav'
    ,'container_class' => 'subpages'
    ,'depth' => 0
    ,'walker' => new SH_Child_Only_Walker()
 ));
?>
jchamb
sumber
Saya ingin menunjukkan komentar @ Stoosh yang menunjuk di sini. stackoverflow.com/questions/5826609/... karena ini adalah solusi lain yang bagus
jchamb
0

Saya memiliki pengalaman serupa. Anda mungkin ingin berpikir tentang memindahkan halaman logika keluar dari alat bantu jalan. Pada dasarnya, kompilasi hierarki halaman saat ini sebagai objek. Kemudian gunakan parameter 'kecualikan' di fungsi wp_nav_menu. Sekarang halaman yang dikecualikan akan tergantung pada apakah halaman saat ini memiliki anak. Jika tidak ada anak yang menunjukkan saudara laki-laki; jika anak-anak &&& anak-anak itu adalah akhir dari garis perlihatkan saudara dan anak; jika anak-anak && dan cucu ada, singkirkan saudara dan tunjukkan anak-anak dan cucu.

Steve Fischer
sumber
Apa excludeparameter ini yang Anda rujuk? Saya melihat dokumentasi dan tidak melihat referensi untuk itu.
Chris Krycho
1
Saya minta maaf saya salah. Anda benar bahwa tidak ada parameter 'kecualikan'. Saya bermaksud menggunakan fungsi "wp_list_pages".
Steve Fischer
Sangat bagus, dan jangan khawatir. Saya hanya ingin tahu apakah ada sesuatu yang tidak berdokumen tetapi di bagian belakang — saya pernah melihat itu terjadi sebelumnya. Terima kasih sudah membereskannya! Saya tidak berpikir untuk menggunakan wp_list_pages()dalam konteks ini, jadi itu ide yang menarik.
Chris Krycho