Bộ lọc wp_nav_menu ()


9

Tôi cố gắng chia điều hướng của mình thành 3 thanh điều hướng đơn (cấp 1, cấp 2 và cấp 3 +). Ba vì chúng được phân tách trên trang web và chúng chỉ xuất hiện tùy thuộc vào trang hiện tại.

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

Thanh điều hướng đầu tiên chứa cấp 1 luôn hiển thị. Thanh điều hướng thứ hai (cấp 2) chỉ khi tôi hiện đang ở trang cha tương ứng. Điều tương tự cũng xảy ra với thanh điều hướng thứ ba (cấp 3+, cộng với vì thanh điều hướng này cũng sẽ chứa các trang phụ và trang phụ ... của cấp 3).

Tóm lại: Tôi muốn hiển thị tất cả các menu cha trong các nút điều hướng của chúng và chỉ các phần tử con trực tiếp của trang hiện tại.

Những gì tôi đã cố gắng:

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

Gọi cái này trong tiêu đề.php của tôi: <?php my_nav_menu( array( 'echo' => false , 'navlevel' => 1 ) ); ?>

Tuy nhiên, $argsđược đặt thành các giá trị mặc định và mục nhập tùy chỉnh của tôi navlevelkhông được hiển thị trong bộ lọc.

Làm thế nào tôi có thể chia thanh điều hướng của tôi như mô tả? Làm cách nào để đặt tùy chỉnh $args?


2
Chúc một ngày tốt lành và chào mừng đến với WPSE. Tôi phải chúc mừng bạn về một câu hỏi được xây dựng hoành tráng cho một bộ đếm thời gian đầu tiên. Các câu hỏi được xây dựng tốt mà rõ ràng luôn Nhận được rất nhiều sự chú ý với câu trả lời tốt. +1
Pieter Goosen

3
Câu trả lời cho điều này liên quan đến một lớp Walker tùy chỉnh, có lẽ điều này sẽ hỗ trợ cho bất kỳ người trả lời tiềm năng nào
Tom J Nowell

Cảm ơn bạn. Tôi chỉ đào vào php / wp vào cuối tuần này nên tôi không quen. Tôi đã thử một Walker tùy chỉnh, tuy nhiên Walker chỉ xử lý một mục duy nhất tại một thời điểm, vì vậy tôi không thể so sánh nó với mục hiện tại. Và một bộ lọc không chấp nhận đối số tùy chỉnh của tôi. Hmmm ...
vô nghĩa

Câu trả lời:


3

Tôi nghĩ rằng tôi đã có câu trả lời:

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

Đây là một mẹo nhỏ: cho phép tôi thay đổi các menuitem và các đối số tùy chỉnh vẫn có sẵn. Tôi vô tình móc bộ lọc vàowp_get_nav_menu_items thay vì wp_nav_menu_objects. Tôi vẫn gặp vấn đề với bộ lọc, tuy nhiên đây có thể là một số lỗi logic ..

EDIT: tôi sẽ giải quyết vấn đề của mình bằng cách kết hợp thanh điều hướng cấp 2 và thanh điều hướng cấp 3+ thành một và tách chúng bằng css

Đây là phần php hiện tại:

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

Có vẻ tốt với tôi từ cái nhìn đầu tiên. Bạn có vấn đề với mã đó? Sidenote: Bạn có thể rút ngắn tuyên bố đầu tiên của mình:$echo = ! isset( $args['echo'] ) ?: $args['echo'];
kaiser

1

Dường như với tôi rằng bạn có thể xử lý việc này thông qua CSS ở chỗ bạn có thể ẩn các tùy chọn menu cấp thấp hơn theo mặc định, sau đó chọn hiển thị chúng nếu chúng có các lớp nhất định phía trên chúng.

Trên trang Codex này , bạn có thể thấy các lớp menu (và trên chính trang của bạn). Vì vậy, đối với "cấp thứ hai" mà bạn đã mô tả, giả sử menu cấp thứ nhất là cấp 1 - không phải 0.

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

Và sau đó một cái gì đó tương tự cho cấp độ tiếp theo xuống:

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

Rõ ràng thay thế "khối" bằng "khối nội tuyến" hoặc bất cứ điều gì các menu của bạn thường được đặt thành.

Bạn có thể cần chơi xung quanh để tìm ra sự kết hợp đúng đắn của các lớp, nhưng tôi đã gặp may mắn với phương pháp này trước đây. WP giảm một tấn các lớp học ở đó, cũng có thể sử dụng chúng.


Cảm ơn, tôi sẽ sử dụng một số lớp trong css cho các thanh điều hướng của mình! :)
vô nghĩa

Nếu bạn đã kết thúc sử dụng giải pháp này, bạn có thể vui lòng đánh dấu câu trả lời của tôi là được chấp nhận không? Cảm ơn bạn.
Amanda Giles
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.