กรอง wp_nav_menu ()


9

ฉันพยายามแยกการนำทางของฉันออกเป็น 3 แถบนำทางเดียว (ระดับ 1 ระดับ 2 และระดับ 3 +) สามเพราะพวกเขาถูกแยกออกจากเว็บไซต์และพวกเขาควรปรากฏเฉพาะขึ้นอยู่กับหน้าปัจจุบัน

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

navbar แรกที่มีระดับ 1 จะมองเห็นได้เสมอ navbar ที่สอง (ระดับ 2) ต่อเมื่อ im บนเพจพาเรนต์ที่เกี่ยวข้องเท่านั้น เช่นเดียวกับแถบนำทางที่สาม (ระดับ 3+ บวกเนื่องจากแถบนำทางนี้จะมีหน้าย่อยและหน้าย่อย ... ของระดับ 3)

กล่าวโดยย่อ: ฉันต้องการแสดงเมนูพาเรนต์ทั้งหมดใน navbars ของพวกเขาและแสดงเฉพาะรายการย่อยของเพจปัจจุบัน

สิ่งที่ฉันพยายาม:

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

เรียกสิ่งนี้ในส่วนหัวของฉัน php: <?php my_nav_menu( array( 'echo' => false , 'navlevel' => 1 ) ); ?>

อย่างไรก็ตาม$argsถูกตั้งค่าเป็นค่าเริ่มต้นและรายการที่กำหนดเองของฉันnavlevelไม่แสดงในตัวกรอง

ฉันจะแยก navbar ตามที่อธิบายไว้ได้อย่างไร ฉันจะตั้งค่าผู้ร่วมกำหนดเองได้$argsอย่างไร


2
ขอให้เป็นวันที่ดีและยินดีต้อนรับสู่ WPSE ฉันต้องแสดงความยินดีกับคุณในคำถามที่สร้างขึ้นมาอย่างยิ่งใหญ่สำหรับตัวจับเวลาแรก คำถามที่ถูกสร้างมาอย่างดีที่ชัดเจนมักจะได้รับความสนใจอย่างมากพร้อมคำตอบที่ดี +1
Pieter Goosen

3
คำตอบของเรื่องนี้เกี่ยวข้องกับคลาสวอล์คเกอร์ที่กำหนดเองบางทีนี่อาจช่วยผู้ให้คำตอบที่มีศักยภาพ
Tom J Nowell

ขอบคุณ. ฉันขุดเป็น php / wp เฉพาะสุดสัปดาห์นี้ดังนั้นฉันจึงไม่คุ้นเคย ฉันลองใช้วอล์คเกอร์ที่กำหนดเองอย่างไรก็ตามวอล์คเกอร์จัดการเพียงรายการเดียวในแต่ละครั้งดังนั้นฉันจึงไม่สามารถเปรียบเทียบกับรายการปัจจุบันได้ และตัวกรองไม่ยอมรับอาร์กิวเมนต์ที่กำหนดเองของฉัน อืม ...
อนุมัติ

คำตอบ:


3

ฉันคิดว่าฉันได้คำตอบ:

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

นี่เป็นกลอุบาย: ให้ฉันเปลี่ยน menuitems และ args ที่กำหนดเองยังคงมีอยู่ ฉันตั้งใจติดยาเสพติดเข้ามาในตัวกรองแทนwp_get_nav_menu_items wp_nav_menu_objectsฉันยังคงมีปัญหากับการกรองอย่างไรก็ตามสิ่งเหล่านี้อาจเป็นข้อบกพร่องเชิงตรรกะบางอย่าง ..

แก้ไข: ฉันจะแก้ไขปัญหาของฉันโดยรวม navbar ระดับ 2 และระดับ Navbar 3+ เป็นหนึ่งและแยกพวกเขาด้วย CSS

นี่คือส่วน php ปัจจุบัน:

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

ดูดีสำหรับฉันได้อย่างรวดเร็วก่อน คุณมีปัญหากับรหัสนั้นหรือไม่? Sidenote: คุณสามารถทำให้ข้อความสั้นแรกของคุณสั้นลง:$echo = ! isset( $args['echo'] ) ?: $args['echo'];
kaiser

1

สำหรับฉันแล้วคุณสามารถจัดการสิ่งนี้ได้ด้วย CSS โดยที่คุณสามารถซ่อนตัวเลือกเมนูระดับล่างโดยค่าเริ่มต้นแล้วเลือกที่จะแสดงหากพวกเขามีชั้นเรียนบางอย่างเหนือพวกเขา

บนเพจ Codex นี้คุณสามารถดูคลาสเมนู (และบนเพจของคุณเอง) ดังนั้นสำหรับ "ระดับที่สอง" ที่คุณอธิบายสมมติว่าเมนูระดับแรกคือระดับ 1 - ไม่ใช่ 0

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

แล้วสิ่งที่คล้ายกันสำหรับระดับถัดไปลง:

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

เห็นได้ชัดว่าแทนที่ "block" ด้วย "inline-block" หรืออะไรก็ตามที่เมนูของคุณตั้งไว้

คุณอาจต้องเล่นเพื่อหาชุดค่าผสมที่ถูกต้อง แต่ฉันโชคดีกับวิธีนี้มาก่อน WP ลดจำนวนคลาสลงที่นั่นและอาจใช้คลาสเหล่านั้นด้วย


ขอบคุณฉันจะใช้คลาสใน css สำหรับแถบนำทางของฉัน! :)
ชดเชย

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