Filter wp_nav_menu ()

9

Saya mencoba untuk membagi navigasi saya menjadi 3 bar navigasi tunggal (level 1, level 2 dan level3 +). Tiga karena mereka dipisahkan oleh situs dan seharusnya hanya muncul tergantung pada halaman saat ini.

-0-------1--------2-------3+- level/depth
Home
 |
 |\___ Lobby
 |
 |\___ Projects
 |       |\___ Project A
 |       |       |\___ Review
 |       |       |\___ Comments
 |       |       \____ Download
 |       \____ Project B
 |               |\___ Review
 |               |\___ Comments
 |               \____ Download
 |\___ Blog
 |
 \____ About
         |\___ Legal
         \____ Contact

Navbar pertama yang berisi level 1 selalu terlihat. Navbar kedua (level 2) hanya ketika saya saat ini pada halaman induk yang sesuai. Hal yang sama berlaku untuk navbar ketiga (level 3+, plus karena navbar ini juga akan berisi sub halaman dan sububuh halaman ... dari level 3).

Singkatnya: Saya ingin menampilkan semua menu induk di navbars mereka dan hanya anak-anak langsung dari halaman saat ini.

Apa yang saya coba:

function my_nav_menu( $args = array() )
{
    $echo = isset( $args['echo'] ) ? (bool)( $args['echo'] ) : true;
    $args['echo'] = false;

    add_filter( 'wp_get_nav_menu_items' , 'my_nav_menu_filter' , 666 , 3 );

    $menu = wp_nav_menu( $args );

    remove_filter( 'wp_nav_menu_objects' , 'my_nav_menu_filter' , 666 );

    if( $echo )
        echo $menu;
    else
        return $menu;
}

function my_nav_menu_filter( $items , $menu , $args )
{
    //var_dump( $args );

    $navLevel = isset( $args['navlevel'] ) ? (int)( $args['navlevel'] ) : 0;

    //echo 'navlevel = ' . $args['navlevel'] . ' | ' . $navLevel;

    if( $navLevel == 1 )
    {
        foreach( $items as $key => $item )
        {
            if( $item->menu_item_parent != 0 )
                unset( $items[$key] );
        }
    }
    else if( $navLevel == 2 )
    {
        foreach( $items as $key => $item )
        {
            if( $item->menu_item_parent != 0 )
            {
                $page = get_page( $item->menu_item_parent );

                if( $page->menu_item_parent == 0 )
                    continue;
            }

            unset( $items[$key] );
        }
    }
    else if( $navLevel == 3 )
    {
        foreach( $items as $key => $item )
        {
            if( $item->menu_item_parent != 0 )
            {
                $page = get_page( $item->menu_item_parent );

                if( $page->menu_item_parent != 0 )
                    continue;
            }

            unset( $items[$key] );
        }
    }
    else
    {
        //var_dump( $items );
    }

    return $items;
}

Memanggil ini di header.php saya: <?php my_nav_menu( array( 'echo' => false , 'navlevel' => 1 ) ); ?>

Namun $argsdiatur ke nilai default dan entri kustom saya navleveltidak ditampilkan di filter.

Bagaimana saya bisa membagi navbar saya seperti yang dijelaskan? Bagaimana cara saya mengatur kustom-masuk saya $args?

nonsensasi
sumber
2
Selamat siang dan selamat datang di WPSE. Saya harus memberi selamat kepada Anda atas pertanyaan epik yang dibuat untuk timer pertama. Pertanyaan yang dibangun dengan baik yang jelas selalu menerima banyak perhatian dengan jawaban yang baik. +1
Pieter Goosen
3
Jawabannya melibatkan kelas kustom Walker, mungkin ini akan membantu setiap penjawab potensial
Tom J Nowell
Terima kasih. Saya menggali ke dalam php / wp hanya akhir pekan ini jadi saya tidak terbiasa ini. Saya mencoba Walker khusus, namun Walker hanya menangani satu item saja, jadi saya tidak bisa membandingkannya dengan item saat ini. Dan filter tidak menerima argumen khusus saya. Hmmm ...
nonsensation

Jawaban:

3

Saya pikir saya mendapat jawabannya:

function my_nav_menu( $args = array() )
{
    $echo = isset( $args['echo'] ) ? (bool)( $args['echo'] ) : true;

    $args['echo'] = false;

    add_filter( 'wp_nav_menu_objects' , 'my_filter_nav_menu' , 100 , 2 );

    $menu = wp_nav_menu( $args );

    remove_filter( 'wp_nav_menu_objects' , 'my_filter_nav_menu' , 100, 2 );

    if( $echo )
        echo $menu;
    else
        return $menu;
}

Ini caranya: izinkan saya mengubah menu dan argumen khusus masih tersedia. Saya tidak sengaja menghubungkan filter ke wp_get_nav_menu_itemsbukan wp_nav_menu_objects. Saya masih mengalami masalah dengan penyaringan, namun ini mungkin beberapa bug logis ..

EDIT: saya akan menyelesaikan masalah saya dengan menggabungkan navbar level 2 dan navbar level 3+ menjadi satu dan memisahkannya dengan css

inilah bagian php saat ini:

function serthy_filter_nav_menu( $items , $args )
{
    $argArray = (array)( $args );

    if( isset( $argArray['toplevel'] ) )
    {
        foreach( $items as $key => $item )
        {
            if( $item->menu_item_parent != 0 )
                unset( $items[$key] );
        }

        return $items;
    }

    global $post;

    $arr = array();

    foreach( $items as $key => $item )
    {
        $parentIDs = get_post_ancestors( $item->ID );

        foreach( $parentIDs as $i => $parentID )
        {
            if( $parentID == $post->ID )
            {
                array_push( $arr , $item );

                break;
            }
        }
    }

    return $arr;
}
nonsensasi
sumber
Terlihat bagus untuk saya pada pandangan pertama. Apakah Anda memiliki masalah dengan kode itu? Sidenote: Anda dapat mempersingkat pernyataan pertama Anda:$echo = ! isset( $args['echo'] ) ?: $args['echo'];
kaiser
1

Menurut saya, Anda dapat menangani ini melalui CSS karena Anda dapat menyembunyikan opsi menu tingkat bawah secara default, dan kemudian memilih untuk memperlihatkannya jika mereka memiliki kelas tertentu di atasnya.

Pada halaman Codex ini , Anda dapat melihat kelas menu (dan pada halaman Anda sendiri). Jadi untuk "tingkat kedua" yang Anda jelaskan, dengan asumsi menu tingkat pertama adalah tingkat 1 - bukan 0.

ul > li > ul.sub-menu { display: none; }  /* Hide by default */
ul > li.current-menu-parent > ul.sub-menu { display: block; } /* Show menu */

Dan kemudian sesuatu yang serupa untuk level berikutnya turun:

ul > li > ul.sub-menu > li > ul.sub-menu{ display: none; }  /* Hide by default */
ul > li > ul.sub-menu > li.current-menu-parent > ul.sub-menu { display: block; }

Jelas ganti "blokir" dengan "blok-inline" atau apa pun menu yang biasanya diatur untuk Anda.

Anda mungkin perlu bermain-main untuk menemukan kombinasi kelas yang tepat, tetapi saya sudah beruntung dengan metode ini sebelumnya. WP menjatuhkan satu ton kelas di sana, mungkin juga menggunakannya.

Amanda Giles
sumber
Terima kasih, saya akan menggunakan beberapa kelas di css untuk bilah nav saya! :)
nonsensation
Jika Anda akhirnya menggunakan solusi ini, dapatkah Anda menandai jawaban saya sebagai diterima? Terima kasih.
Amanda Giles