แสดงส่วน / สาขาของโครงสร้างเมนูโดยใช้ wp_nav_menu ()


109

ฉันมีเมนูที่กำหนดไว้ใน WP Admin ที่มีลักษณะเช่นนี้:

ข้อความแสดงแทน

ฉันต้องการที่จะแสดงลิงค์ลูกทั้งหมดบนแถบด้านข้างทุกครั้งที่ฉันอยู่ที่หน้าหลัก ตัวอย่างเช่นหากผู้ใช้อยู่ในหน้า "เกี่ยวกับเรา" ฉันต้องการรายการลิงก์ 4 ที่เน้นด้วยสีเขียวเพื่อให้ปรากฏบนแถบด้านข้าง

ฉันดูเอกสารประกอบสำหรับwp_nav_menu ()และดูเหมือนไม่มีวิธีการติดตั้งในตัวเพื่อระบุโหนดเฉพาะของเมนูที่กำหนดเพื่อใช้เป็นจุดเริ่มต้นเมื่อสร้างลิงก์

ฉันสร้างโซลูชันสำหรับสถานการณ์ที่คล้ายกันซึ่งอาศัยความสัมพันธ์ที่สร้างโดยเพจหลัก แต่ฉันกำลังมองหาโซลูชันที่ใช้ระบบเมนูโดยเฉพาะ ความช่วยเหลือใด ๆ ที่จะได้รับการชื่นชม


2
ดังนั้นคุณต้องการบำรุงรักษาเมนูทั้งหมดเป็นเมนูที่กำหนดเอง แต่สร้างวอล์คเกอร์ที่กำหนดเองซึ่งแสดงมันขยายเฉพาะทรีย่อยที่ใช้งานอยู่? ชอบรหัสนี้แต่ขยาย wp_nav_menu แทนที่จะเป็น wp_list_pages? ฉันเพิ่งทำอะไรบางอย่างที่คล้ายกันและสามารถโพสต์รหัสถ้า thats สิ่งที่คุณกำลังมองหา ...
goldenapples

1
@ goldenapples นั่นคือสิ่งที่ฉันเป็นอย่างแน่นอน หากคุณไม่รังเกียจที่จะโพสต์รหัสของคุณเป็นคำตอบฉันจะขอบคุณมาก
jessegavin

1
ฉันสงสัยว่าฟังก์ชั่นที่มีประโยชน์ที่เห็นได้ชัดนั้นยังไม่ได้สร้าง นั่นเป็นประโยชน์อย่างมากสำหรับเว็บไซต์ใด ๆ ที่ใช้ "CMS"
hakre

ฉันพยายามที่จะแก้ปัญหาข้างต้นหรือสิ่งที่คล้ายกัน เป็นอีกทางเลือกหนึ่งที่ฉันใช้วิธีแก้ปัญหา CSS ที่นี่: stackoverflow.com/q/7640837/518169
hyperknot

คำตอบ:


75

สิ่งนี้ยังอยู่ในใจของฉันดังนั้นฉันจึงกลับมาทบทวนอีกครั้งและรวบรวมวิธีแก้ปัญหานี้ซึ่งไม่พึ่งพาบริบทที่มาก:

add_filter( 'wp_nav_menu_objects', 'submenu_limit', 10, 2 );

function submenu_limit( $items, $args ) {

    if ( empty( $args->submenu ) ) {
        return $items;
    }

    $ids       = wp_filter_object_list( $items, array( 'title' => $args->submenu ), 'and', 'ID' );
    $parent_id = array_pop( $ids );
    $children  = submenu_get_children_ids( $parent_id, $items );

    foreach ( $items as $key => $item ) {

        if ( ! in_array( $item->ID, $children ) ) {
            unset( $items[$key] );
        }
    }

    return $items;
}

function submenu_get_children_ids( $id, $items ) {

    $ids = wp_filter_object_list( $items, array( 'menu_item_parent' => $id ), 'and', 'ID' );

    foreach ( $ids as $id ) {

        $ids = array_merge( $ids, submenu_get_children_ids( $id, $items ) );
    }

    return $ids;
}

การใช้

$args = array(
    'theme_location' => 'slug-of-the-menu', // the one used on register_nav_menus
    'submenu' => 'About Us', // could be used __() for translations
);

wp_nav_menu( $args );

เทคนิคน่ารัก! ฉันขอสิ่งที่อาจเกี่ยวข้องกับสิ่งนี้: คุณจะแสดงเนื้อหาของหน้าเมนูย่อยที่ระบุไว้ในเทมเพลตได้อย่างไร
daniel.tosaba

2
@ daniel.tosaba คุณจะต้องใช้คลาสย่อยหรือใช้ตัวกรองในWalker_Nav_Menuชั้นเรียน เช่นเดียวกับทุกเมนูมีความคิดเห็นมากเกินไป - ถามคำถามใหม่เกี่ยวกับมันหรือไม่
Rarst


3
ช่างเป็นคำตอบที่วิเศษมาก ขอบคุณมาก. นี่ควรเป็นตัวเลือกเริ่มต้นภายใน WordPress
dotty

3
เรียบร้อยจริงๆ หากใครสนใจที่จะทำเช่นเดียวกัน แต่โดยใช้ ID หน้าให้เปลี่ยนwp_filter_object_listบรรทัดเป็นwp_filter_object_list( $items, array( 'object_id' => $args->submenu ), 'and', 'ID' );
Ben

14

@goldenapples: Walker Class ของคุณไม่ทำงาน แต่ความคิดนั้นดีจริงๆ ฉันสร้างวอล์คเกอร์ตามความคิดของคุณ:

class Selective_Walker extends Walker_Nav_Menu
{
    function walk( $elements, $max_depth) {

        $args = array_slice(func_get_args(), 2);
        $output = '';

        if ($max_depth < -1) //invalid parameter
            return $output;

        if (empty($elements)) //nothing to walk
            return $output;

        $id_field = $this->db_fields['id'];
        $parent_field = $this->db_fields['parent'];

        // flat display
        if ( -1 == $max_depth ) {
            $empty_array = array();
            foreach ( $elements as $e )
                $this->display_element( $e, $empty_array, 1, 0, $args, $output );
            return $output;
        }

        /*
         * need to display in hierarchical order
         * separate elements into two buckets: top level and children elements
         * children_elements is two dimensional array, eg.
         * children_elements[10][] contains all sub-elements whose parent is 10.
         */
        $top_level_elements = array();
        $children_elements  = array();
        foreach ( $elements as $e) {
            if ( 0 == $e->$parent_field )
                $top_level_elements[] = $e;
            else
                $children_elements[ $e->$parent_field ][] = $e;
        }

        /*
         * when none of the elements is top level
         * assume the first one must be root of the sub elements
         */
        if ( empty($top_level_elements) ) {

            $first = array_slice( $elements, 0, 1 );
            $root = $first[0];

            $top_level_elements = array();
            $children_elements  = array();
            foreach ( $elements as $e) {
                if ( $root->$parent_field == $e->$parent_field )
                    $top_level_elements[] = $e;
                else
                    $children_elements[ $e->$parent_field ][] = $e;
            }
        }

        $current_element_markers = array( 'current-menu-item', 'current-menu-parent', 'current-menu-ancestor' );  //added by continent7
        foreach ( $top_level_elements as $e ){  //changed by continent7
            // descend only on current tree
            $descend_test = array_intersect( $current_element_markers, $e->classes );
            if ( !empty( $descend_test ) ) 
                $this->display_element( $e, $children_elements, 2, 0, $args, $output );
        }

        /*
         * if we are displaying all levels, and remaining children_elements is not empty,
         * then we got orphans, which should be displayed regardless
         */
         /* removed by continent7
        if ( ( $max_depth == 0 ) && count( $children_elements ) > 0 ) {
            $empty_array = array();
            foreach ( $children_elements as $orphans )
                foreach( $orphans as $op )
                    $this->display_element( $op, $empty_array, 1, 0, $args, $output );
         }
        */
         return $output;
    }
}

ตอนนี้คุณสามารถใช้:

<?php wp_nav_menu( 
   array(
       'theme_location'=>'test', 
       'walker'=>new Selective_Walker() ) 
   ); ?>

ผลลัพธ์คือรายการที่มีองค์ประกอบรากปัจจุบันและเป็นลูก (ไม่ใช่ลูกหลาน) Def: องค์ประกอบรูท: = รายการเมนูระดับบนสุดที่สอดคล้องกับหน้าปัจจุบันหรือเป็นพาเรนต์ของเพจปัจจุบันหรือพาเรนต์ของพาเรนต์ ...

สิ่งนี้ไม่ได้ตอบคำถามเดิมอย่างแท้จริง แต่เกือบจะเนื่องจากยังมีรายการระดับสูงสุด นี่เป็นสิ่งที่ดีสำหรับฉันเพราะฉันต้องการให้องค์ประกอบระดับบนสุดเป็นพาดหัวของแถบด้านข้าง หากคุณต้องการกำจัดสิ่งนี้คุณอาจต้องแทนที่ display_element หรือใช้ HTML-Parser


12

สวัสดี@ jessegavin :

เมนู Nav จะถูกเก็บไว้ในประเภทโพสต์ที่กำหนดเองและ taxonomies ที่กำหนดเอง แต่ละเมนูถูกจัดเก็บเป็นคำศัพท์ (เช่น"เกี่ยวกับเมนู"ซึ่งพบได้ในwp_terms) ของ Taxonomy ที่กำหนดเอง (เช่นที่nav_menuพบในwp_term_taxonomy)

รายการเมนู Nav แต่ละรายการจะถูกจัดเก็บเป็นโพสต์ของpost_type=='nav_menu_item'(เช่น"เกี่ยวกับ บริษัท " ที่พบในwp_posts) โดยมีแอททริบิวที่จัดเก็บไว้เป็นโพสต์เมตา (ในwp_postmeta) โดยใช้meta_keyคำนำหน้า_menu_item_*ซึ่ง_menu_item_menu_item_parentID ของรายการเมนูหลัก

ความสัมพันธ์ระหว่างเมนูและรายการเมนูที่ถูกเก็บไว้ในwp_term_relationshipsสถานที่ที่object_idเกี่ยวข้องกับ$post->IDสำหรับ Nav รายการเมนูและ$term_relationships->term_taxonomy_idเกี่ยวข้องกับเมนูที่กำหนดไว้รวมในและwp_term_taxonomywp_terms

ฉันค่อนข้างแน่ใจว่ามันเป็นไปได้ที่จะขอทั้งสอง'wp_update_nav_menu'และ'wp_update_nav_menu_item'สร้างเมนูจริงwp_termsและความสัมพันธ์แบบคู่ขนานในwp_term_taxonomyและwp_term_relationshipsที่ทุกรายการเมนู Nav ที่มีรายการเมนูย่อย Nav ก็กลายเป็นเมนู Nav ของตัวเอง

คุณต้องการที่จะขอ 'wp_get_nav_menus' (ซึ่งผมแนะนำให้เพิ่มใน WP 3.0 ตามงานที่คล้ายกันที่ฉันทำเมื่อไม่กี่เดือนที่ผ่านมา)เพื่อให้แน่ใจว่าเมนู Nav ที่สร้างขึ้นของคุณจะไม่ปรากฏขึ้นเพื่อจัดการโดยผู้ใช้ในผู้ดูแลระบบ ออกไปจากการซิงค์อย่างรวดเร็วจริง ๆ แล้วคุณจะมีข้อมูลฝันร้ายในมือของคุณ

เสียงเหมือนโครงการสนุกและมีประโยชน์ แต่ก็เป็นรหัสนิด ๆ หน่อย ๆ และการทดสอบกว่าที่ฉันสามารถที่จะแก้ไขปัญหาในขณะนี้ส่วนหนึ่งเป็นเพราะอะไรที่ประสานข้อมูลที่มีแนวโน้มที่จะ PITA เมื่อมันมาถึงโต๊ะรีดออก bugs ทั้งหมด(และเพราะ ลูกค้าที่จ่ายเงินกำลังกดฉันเพื่อให้เสร็จลุล่วง :)แต่ด้วยข้อมูลข้างต้นฉันค่อนข้างจะเป็นนักพัฒนาปลั๊กอิน WordPress ที่แรงบันดาลใจสามารถเขียนโค้ดได้หากพวกเขาต้องการ

แน่นอนว่าคุณต้องตระหนักในตอนนี้ถ้าคุณใช้รหัสคุณจำเป็นต้องโพสต์กลับมาที่นี่เพื่อให้เราได้รับประโยชน์จากการบริจาคของคุณ! :-)


ฉันไม่แน่ใจว่าฉันกำลังติดตามสิ่งที่คุณพูด ฉันกำลังมองหาวิธีแก้ปัญหาแบบอ่านอย่างเดียวสำหรับการแสดง "เมนูย่อย" ที่เกี่ยวข้องกับหน้าปัจจุบันที่ผู้ใช้อยู่ เรากำลังพูดถึงสิ่งเดียวกันหรือไม่? - ฉันขอขอบคุณคำอธิบายที่ลึกซึ้งยิ่งขึ้นเกี่ยวกับสคีมาฐานข้อมูล
jessegavin

@jessegavin - ใช่ถ้าคุณต้องการที่จะเรียกwp_nav_menu()แล้วคุณจะต้องโคลนเมนูเพราะเป็นคู่แน่นกับโครงสร้างเมนูwp_nav_menu() ตัวเลือกอื่นคือการคัดลอกwp_nav_menu()รหัสและทำการแก้ไขที่จำเป็นเพื่อแสดงเป็นเมนูย่อย
MikeSchinkel

10

นี่เป็นส่วนเสริมสำหรับวอล์คเกอร์ซึ่งควรทำสิ่งที่คุณต้องการ:

class Selective_Walker extends Walker_Nav_Menu
{

    function walk( $elements, $max_depth) {

        $args = array_slice(func_get_args(), 2);
        $output = '';

        if ($max_depth < -1) //invalid parameter
            return $output;

        if (empty($elements)) //nothing to walk
            return $output;

        $id_field = $this->db_fields['id'];
        $parent_field = $this->db_fields['parent'];

        // flat display
        if ( -1 == $max_depth ) {
            $empty_array = array();
            foreach ( $elements as $e )
                $this->display_element( $e, $empty_array, 1, 0, $args, $output );
            return $output;
        }

        /*
         * need to display in hierarchical order
         * separate elements into two buckets: top level and children elements
         * children_elements is two dimensional array, eg.
         * children_elements[10][] contains all sub-elements whose parent is 10.
         */
        $top_level_elements = array();
        $children_elements  = array();
        foreach ( $elements as $e) {
            if ( 0 == $e->$parent_field )
                $top_level_elements[] = $e;
            else
                $children_elements[ $e->$parent_field ][] = $e;
        }

        /*
         * when none of the elements is top level
         * assume the first one must be root of the sub elements
         */
        if ( empty($top_level_elements) ) {

            $first = array_slice( $elements, 0, 1 );
            $root = $first[0];

            $top_level_elements = array();
            $children_elements  = array();
            foreach ( $elements as $e) {
                if ( $root->$parent_field == $e->$parent_field )
                    $top_level_elements[] = $e;
                else
                    $children_elements[ $e->$parent_field ][] = $e;
            }
        }

        $current_element_markers = array( 'current-menu-item', 'current-menu-parent', 'current-menu-ancestor' );

        foreach ( $top_level_elements as $e ) {

            // descend only on current tree
            $descend_test = array_intersect( $current_element_markers, $e->classes );
            if ( empty( $descend_test ) )  unset ( $children_elements );

            $this->display_element( $e, $children_elements, $max_depth, 0, $args, $output );
        }

        /*
         * if we are displaying all levels, and remaining children_elements is not empty,
         * then we got orphans, which should be displayed regardless
         */
        if ( ( $max_depth == 0 ) && count( $children_elements ) > 0 ) {
            $empty_array = array();
            foreach ( $children_elements as $orphans )
                foreach( $orphans as $op )
                    $this->display_element( $op, $empty_array, 1, 0, $args, $output );
         }

         return $output;
    }

}

ตามรหัสของ mfields อย่างไม่รัดกุมฉันอ้างอิงในความคิดเห็นของฉันก่อนหน้านี้ สิ่งที่มันทำคือการตรวจสอบเมื่อเดินเมนูเพื่อดูว่าองค์ประกอบปัจจุบันคือ (1) รายการเมนูปัจจุบันหรือ (2) บรรพบุรุษของรายการเมนูปัจจุบันและขยายทรีย่อยด้านล่างหากเงื่อนไขใดเงื่อนไขหนึ่งเป็นจริง . หวังว่านี่จะเป็นประโยชน์สำหรับคุณ

หากต้องการใช้งานเพียงแค่เพิ่มอาร์กิวเมนต์ "วอล์คเกอร์" เมื่อคุณเรียกเมนูเช่น:

<?php wp_nav_menu( 
   array(
       'theme_location'=>'test', 
       'walker'=>new Selective_Walker() ) 
   ); ?>

โอ้ ... ฉันเพิ่งอ่านคำถามของคุณอีกครั้งและตระหนักว่าฉันเข้าใจผิดในตอนแรก วอล์คเกอร์นี้จะแสดงรายการเมนูระดับบนสุดอื่น ๆ ทั้งหมด แต่ไม่ขยาย นี่ไม่ใช่สิ่งที่คุณต้องการจะทำ แต่ถึงกระนั้นรหัสนี้สามารถแก้ไขได้ในแบบที่คุณต้องการ เพียงแค่ดูที่ห่วงผ่านและเพิ่มการทดสอบของคุณเองก่อนที่จะเรียกร้องให้$top_level_elements $this->display_element
goldenapples

เป็นไปได้ไหมที่คลาสนี้จะแสดงความลึกของหน้าย่อยปัจจุบัน? นั่นคือ .. หากฉันมีความลึกสามระดับขึ้นไประดับที่สามและที่ตามมาจะแสดงสำหรับหน้าปัจจุบัน (ย่อย) หรือไม่ ในขณะนี้จะแสดงเฉพาะ A> B และไม่ใช่> C (C เป็นอันดับสาม (ระดับ)
Zolomon

@Zolomon - ฉันไม่แน่ใจว่าฉันเข้าใจคำถามของคุณ สิ่งนี้ควรขยายแผนผังทั้งหมดภายใต้รายการเมนูใด ๆ ด้วยคลาส 'current-menu-item', 'current-menu-parent' หรือ 'current-menu-ancestor' ของคลาส เมื่อฉันทดสอบมันจะแสดงระดับหน้าย่อยทั้งหมดในเมนู คุณต้องการทำอะไร
goldenapples

บางทีคุณต้องการส่งผ่านdepthพารามิเตอร์ไปยังการเรียกไปยังwp_nav_menuในกรณีที่ชุดรูปแบบของคุณมีค่าเริ่มต้นมากกว่า 0 (แสดงทุกระดับ)?
goldenapples

8

อัปเดต: ฉันทำสิ่งนี้ลงในปลั๊กอิน ดาวน์โหลดได้ที่นี่


ฉันต้องแก้ปัญหานี้ด้วยตัวเองและในที่สุดก็ถึงขั้นเขียนตัวกรองผลลัพธ์ของการค้นหาเมนู มันช่วยให้คุณใช้wp_nav_menuตามปกติ แต่เลือกส่วนย่อยของเมนูตามชื่อขององค์ประกอบหลัก เพิ่มsubmenuพารามิเตอร์ให้กับเมนูดังนี้:

wp_nav_menu(array(
  'menu' => 'header',
  'submenu' => 'About Us',
));

คุณสามารถเข้าไปลึกได้หลายระดับโดยใส่เครื่องหมายทับลงใน:

wp_nav_menu(array(
  'menu' => 'header',
  'submenu' => 'About Us/Board of Directors'
));

หรือถ้าคุณต้องการด้วยอาเรย์:

wp_nav_menu(array(
  'menu' => 'header',
  'submenu' => array('About Us', 'Board of Directors')
));

ใช้ชื่อเวอร์ชันบุ้งซึ่งควรทำให้มีการให้อภัยในสิ่งต่างๆเช่นตัวพิมพ์ใหญ่และเครื่องหมายวรรคตอน


เป็นไปได้หรือไม่ที่จะเข้าถึงเมนูย่อยผ่าน ID ฉันหมายถึงรหัสเพจหรือรหัสโพสต์
Digerkam

แยก () เลิกใช้แล้วแทนที่$loc = split( "/", $loc );ด้วยปลั๊กอินด้วย$loc = preg_split( "~/~", $loc );
Floris

ฉันขอแนะนำให้เลือกเมนูย่อย $ เป็นตัวเลือก ดังนั้นคุณยังสามารถดึงข้อมูลเมนูทั้งหมดเมื่อจำเป็น เพิ่มไปยังตัวกรองไปด้านบน: `if (! isset ($ args-> เมนูย่อย)) {return $ items; } `
Floris

8

ฉันรวบรวมชั้นเรียนต่อไปนี้เพื่อตัวเอง มันจะค้นหาผู้ปกครอง nav ด้านบนของหน้าปัจจุบันหรือคุณสามารถให้มัน ID nav ด้านบนเป้าหมายในนวกรรมิกวอล์คเกอร์

class Walker_SubNav_Menu extends Walker_Nav_Menu {
    var $target_id = false;

    function __construct($target_id = false) {
        $this->target_id = $target_id;
    }

    function walk($items, $depth) {
        $args = array_slice(func_get_args(), 2);
        $args = $args[0];
        $parent_field = $this->db_fields['parent'];
        $target_id = $this->target_id;
        $filtered_items = array();

        // if the parent is not set, set it based on the post
        if (!$target_id) {
            global $post;
            foreach ($items as $item) {
                if ($item->object_id == $post->ID) {
                    $target_id = $item->ID;
                }
            }
        }

        // if there isn't a parent, do a regular menu
        if (!$target_id) return parent::walk($items, $depth, $args);

        // get the top nav item
        $target_id = $this->top_level_id($items, $target_id);

        // only include items under the parent
        foreach ($items as $item) {
            if (!$item->$parent_field) continue;

            $item_id = $this->top_level_id($items, $item->ID);

            if ($item_id == $target_id) {
                $filtered_items[] = $item;
            }
        }

        return parent::walk($filtered_items, $depth, $args);
    }

    // gets the top level ID for an item ID
    function top_level_id($items, $item_id) {
        $parent_field = $this->db_fields['parent'];

        $parents = array();
        foreach ($items as $item) {
            if ($item->$parent_field) {
                $parents[$item->ID] = $item->$parent_field;
            }
        }

        // find the top level item
        while (array_key_exists($item_id, $parents)) {
            $item_id = $parents[$item_id];
        }

        return $item_id;
    }
}

Nav โทร:

wp_nav_menu(array(
    'theme_location' => 'main_menu',
    'walker' => new Walker_SubNav_Menu(22), // with ID
));

4

@davidn @hakre สวัสดีฉันมีวิธีแก้ปัญหาที่น่าเกลียดโดยไม่มี HTML-Parser หรือการแทนที่ display_element

 class Selective_Walker extends Walker_Nav_Menu
    {
        function walk( $elements, $max_depth) {

            $args = array_slice(func_get_args(), 2);
            $output = '';

            if ($max_depth < -1) //invalid parameter
                return $output;

            if (empty($elements)) //nothing to walk
                return $output;

            $id_field = $this->db_fields['id'];
            $parent_field = $this->db_fields['parent'];

            // flat display
            if ( -1 == $max_depth ) {
                $empty_array = array();
                foreach ( $elements as $e )
                    $this->display_element( $e, $empty_array, 1, 0, $args, $output );
                return $output;
            }

            /*
             * need to display in hierarchical order
             * separate elements into two buckets: top level and children elements
             * children_elements is two dimensional array, eg.
             * children_elements[10][] contains all sub-elements whose parent is 10.
             */
            $top_level_elements = array();
            $children_elements  = array();
            foreach ( $elements as $e) {
                if ( 0 == $e->$parent_field )
                    $top_level_elements[] = $e;
                else
                    $children_elements[ $e->$parent_field ][] = $e;
            }

            /*
             * when none of the elements is top level
             * assume the first one must be root of the sub elements
             */
            if ( empty($top_level_elements) ) {

                $first = array_slice( $elements, 0, 1 );
                $root = $first[0];

                $top_level_elements = array();
                $children_elements  = array();
                foreach ( $elements as $e) {
                    if ( $root->$parent_field == $e->$parent_field )
                        $top_level_elements[] = $e;
                    else
                        $children_elements[ $e->$parent_field ][] = $e;
                }
            }

            $current_element_markers = array( 'current-menu-item', 'current-menu-parent', 'current-menu-ancestor' );  //added by continent7
            foreach ( $top_level_elements as $e ){  //changed by continent7
                // descend only on current tree
                $descend_test = array_intersect( $current_element_markers, $e->classes );
                if ( !empty( $descend_test ) ) 
                    $this->display_element( $e, $children_elements, 2, 0, $args, $output );
            }

            /*
             * if we are displaying all levels, and remaining children_elements is not empty,
             * then we got orphans, which should be displayed regardless
             */
             /* removed by continent7
            if ( ( $max_depth == 0 ) && count( $children_elements ) > 0 ) {
                $empty_array = array();
                foreach ( $children_elements as $orphans )
                    foreach( $orphans as $op )
                        $this->display_element( $op, $empty_array, 1, 0, $args, $output );
             }
            */

/*added by alpguneysel  */
                $pos = strpos($output, '<a');
            $pos2 = strpos($output, 'a>');
            $topper= substr($output, 0, $pos).substr($output, $pos2+2);
            $pos3 = strpos($topper, '>');
            $lasst=substr($topper, $pos3+1);
            $submenu= substr($lasst, 0, -6);

        return $submenu;
        }
    }

หลังจากลองทุกอย่างแล้วโซลูชันของ Alp เป็นสิ่งเดียวที่ใช้ได้ผลสำหรับฉัน อย่างไรก็ตามปัญหาหนึ่งกับมัน มันแสดงเฉพาะเด็กระดับแรก แต่ไม่แสดงเด็กระดับที่สามหรือสี่ ฉันพยายามมาหลายวันแล้วเพื่อให้มันสำเร็จ ใครรู้วิธีแก้ไขโซลูชันของเขาเช่นนี้? PS มันจะไม่ให้ฉันเพิ่มความคิดเห็นดังนั้นจึงจำเป็นต้องทำมันเป็นคำตอบ
cchiera

3

เอาต์พุตเมนู nav มีคลาสจำนวนมากสำหรับรายการปัจจุบันบรรพบุรุษของไอเท็มปัจจุบัน ฯลฯ ในบางสถานการณ์ฉันสามารถทำสิ่งที่คุณต้องการได้โดยปล่อยให้ nav ต้นไม้ทั้งหมดออกจากนั้นใช้ css เพื่อตัดมันลงไป เฉพาะเด็ก ๆ ของหน้าปัจจุบัน ฯลฯ


3

ฉันสร้างวอล์คเกอร์ที่แก้ไขแล้วซึ่งจะช่วยได้! ไม่สมบูรณ์ - มันปล่อยให้องค์ประกอบที่ว่างเปล่าไม่กี่ แต่มันหลอกลวง การดัดแปลงนั้นเป็นบิต $ current_branch หวังว่ามันจะช่วยให้ใครบางคน!

class Kanec_Walker_Nav_Menu extends Walker {
/**
 * @see Walker::$tree_type
 * @since 3.0.0
 * @var string
 */
var $tree_type = array( 'post_type', 'taxonomy', 'custom' );

/**
 * @see Walker::$db_fields
 * @since 3.0.0
 * @todo Decouple this.
 * @var array
 */
var $db_fields = array( 'parent' => 'menu_item_parent', 'id' => 'db_id' );

/**
 * @see Walker::start_lvl()
 * @since 3.0.0
 *
 * @param string $output Passed by reference. Used to append additional content.
 * @param int $depth Depth of page. Used for padding.
 */
function start_lvl(&$output, $depth) {
    $indent = str_repeat("\t", $depth);
    $output .= "\n$indent<ul class=\"sub-menu\">\n";
}

/**
 * @see Walker::end_lvl()
 * @since 3.0.0
 *
 * @param string $output Passed by reference. Used to append additional content.
 * @param int $depth Depth of page. Used for padding.
 */
function end_lvl(&$output, $depth) {
    global $current_branch;
    if ($depth == 0) $current_branch = false;
    $indent = str_repeat("\t", $depth);
    $output .= "$indent</ul>\n";
}

/**
 * @see Walker::start_el()
 * @since 3.0.0
 *
 * @param string $output Passed by reference. Used to append additional content.
 * @param object $item Menu item data object.
 * @param int $depth Depth of menu item. Used for padding.
 * @param int $current_page Menu item ID.
 * @param object $args
 */
function start_el(&$output, $item, $depth, $args) {
    global $wp_query;
    global $current_branch;

    // Is this menu item in the current branch?
    if(in_array('current-menu-ancestor',$item->classes) ||
    in_array('current-menu-parent',$item->classes) ||
    in_array('current-menu-item',$item->classes)) {
        $current_branch = true; 
    }

    if($current_branch && $depth > 0) {
        $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';

        $class_names = $value = '';

        $classes = empty( $item->classes ) ? array() : (array) $item->classes;
        $classes[] = 'menu-item-' . $item->ID;

        $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
        $class_names = ' class="' . esc_attr( $class_names ) . '"';

        $id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args );
        $id = strlen( $id ) ? ' id="' . esc_attr( $id ) . '"' : '';

        $output .= $indent . '<li' . $id . $value . $class_names .'>';

        $attributes  = ! empty( $item->attr_title ) ? ' title="'  . esc_attr( $item->attr_title ) .'"' : '';
        $attributes .= ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
        $attributes .= ! empty( $item->xfn )        ? ' rel="'    . esc_attr( $item->xfn        ) .'"' : '';
        $attributes .= ! empty( $item->url )        ? ' href="'   . esc_attr( $item->url        ) .'"' : '';

        $item_output = $args->before;
        $item_output .= '<a'. $attributes .'>';
        $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
        $item_output .= '</a>';
        $item_output .= $args->after;

        $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
    }

}

/**
 * @see Walker::end_el()
 * @since 3.0.0
 *
 * @param string $output Passed by reference. Used to append additional content.
 * @param object $item Page data object. Not used.
 * @param int $depth Depth of page. Not Used.
 */
function end_el(&$output, $item, $depth) {
    global $current_branch;
    if($current_branch && $depth > 0) $output .= "</li>\n";
    if($depth == 0) $current_branch = 0;
}

}


3

ตรวจสอบรหัสในปลั๊กอินของฉันหรือใช้เพื่อวัตถุประสงค์ของคุณ;)

ปลั๊กอินนี้เพิ่มวิดเจ็ต "เมนูนำทาง" ที่ได้รับการปรับปรุง มันมีตัวเลือกมากมายซึ่งสามารถตั้งค่าให้ปรับแต่งการแสดงผลของเมนูที่กำหนดเองผ่านเครื่องมือ

คุณสมบัติรวมถึง:

  • ลำดับชั้นที่กำหนดเอง - "เฉพาะรายการย่อยที่เกี่ยวข้อง" หรือ "เฉพาะรายการย่อยที่เกี่ยวข้องอย่างเคร่งครัด"
  • เริ่มต้นความลึกและระดับสูงสุดเพื่อแสดง + จอแบน
  • แสดงรายการเมนูทั้งหมดที่เริ่มต้นด้วยรายการที่เลือก
  • แสดงเฉพาะเส้นทางตรงไปยังองค์ประกอบปัจจุบันหรือเฉพาะ
    รายการย่อยของรายการที่เลือก (ตัวเลือกเพื่อรวมรายการหลัก)
  • คลาสที่กำหนดเองสำหรับบล็อกวิดเจ็ต
  • และพารามิเตอร์เกือบทั้งหมดสำหรับฟังก์ชั่น wp_nav_menu

http://wordpress.org/extend/plugins/advanced-menu-widget/

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