เพิ่มเมนูการนำทางและรายการเมนูโดยทางโปรแกรม


41

ผ่านฟังก์ชั่น API ฉันต้องการกำหนดเมนูนำทางใหม่เลือกในธีมปัจจุบันจากนั้นแทรกเพจเป็นรายการเมนูสองสามหน้า สิ่งนี้จะต้องทำเช่นในการเปิดใช้งานชุดรูปแบบ

ผ่านกระบวนการ (ย้อนกลับที่เจ็บปวดพอสมควร) ในการทำวิศวกรรมย้อนกลับแทรกและอัพเดทฐานข้อมูลด้วยตนเองหลังจากตั้งค่าเมนูนำทางและรายการต่างๆด้วยตนเองฉันได้ทำขั้นตอนต่อไปนี้ด้วยกันโดยที่ 'footer-nav' เป็นรหัสกระสุนของเมนูนำทาง I ' m กำลังสร้าง:

if (!term_exists('footer-nav', 'nav_menu')) {

    $menu = wp_insert_term('Footer nav', 'nav_menu', array('slug' => 'footer-nav'));

    // Select this menu in the current theme
    update_option('theme_mods_'.get_current_theme(), array("nav_menu_locations" => array("primary" => $menu['term_id'])));

    // Insert new page
    $page = wp_insert_post(array('post_title' => 'Blog',
                                 'post_content' => '',
                                 'post_status' => 'publish',
                                 'post_type' => 'page'));

    // Insert new nav_menu_item
    $nav_item = wp_insert_post(array('post_title' => 'News',
                                     'post_content' => '',
                                     'post_status' => 'publish',
                                     'post_type' => 'nav_menu_item'));


    add_post_meta($nav_item, '_menu_item_type', 'post_type');
    add_post_meta($nav_item, '_menu_item_menu_item_parent', '0');
    add_post_meta($nav_item, '_menu_item_object_id', $page);
    add_post_meta($nav_item, '_menu_item_object', 'page');
    add_post_meta($nav_item, '_menu_item_target', '');
    add_post_meta($nav_item, '_menu_item_classes', 'a:1:{i:0;s:0:"";}');
    add_post_meta($nav_item, '_menu_item_xfn', '');
    add_post_meta($nav_item, '_menu_item_url', '');

    wp_set_object_terms($nav_item, 'footer-nav', 'nav_menu');
}

ดูเหมือนว่าจะใช้งานได้ แต่:

  • มันเป็นวิธีที่แข็งแกร่งและสง่างามของการทำมันได้หรือไม่
  • ฉันขาดอะไรบางอย่างที่เห็นได้อย่างชัดเจนว่าจะทำสิ่งนี้ทั้งหมดในหนึ่งบรรทัดของโค้ด?

คำตอบ:


42

ฉันอาจจะเข้าใจผิด แต่ทำไมไม่ใช้wp_create_nav_menu()?

เช่นนี่คือสิ่งที่ฉันต้องทำเพื่อสร้างเมนู BuddyPress ที่กำหนดเองเมื่อตรวจพบ BP ว่าทำงานอยู่:

    $menuname = $lblg_themename . ' BuddyPress Menu';
$bpmenulocation = 'lblgbpmenu';
// Does the menu exist already?
$menu_exists = wp_get_nav_menu_object( $menuname );

// If it doesn't exist, let's create it.
if( !$menu_exists){
    $menu_id = wp_create_nav_menu($menuname);

    // Set up default BuddyPress links and add them to the menu.
    wp_update_nav_menu_item($menu_id, 0, array(
        'menu-item-title' =>  __('Home'),
        'menu-item-classes' => 'home',
        'menu-item-url' => home_url( '/' ), 
        'menu-item-status' => 'publish'));

    wp_update_nav_menu_item($menu_id, 0, array(
        'menu-item-title' =>  __('Activity'),
        'menu-item-classes' => 'activity',
        'menu-item-url' => home_url( '/activity/' ), 
        'menu-item-status' => 'publish'));

    wp_update_nav_menu_item($menu_id, 0, array(
        'menu-item-title' =>  __('Members'),
        'menu-item-classes' => 'members',
        'menu-item-url' => home_url( '/members/' ), 
        'menu-item-status' => 'publish'));

    wp_update_nav_menu_item($menu_id, 0, array(
        'menu-item-title' =>  __('Groups'),
        'menu-item-classes' => 'groups',
        'menu-item-url' => home_url( '/groups/' ), 
        'menu-item-status' => 'publish'));

    wp_update_nav_menu_item($menu_id, 0, array(
        'menu-item-title' =>  __('Forums'),
        'menu-item-classes' => 'forums',
        'menu-item-url' => home_url( '/forums/' ), 
        'menu-item-status' => 'publish'));

    // Grab the theme locations and assign our newly-created menu
    // to the BuddyPress menu location.
    if( !has_nav_menu( $bpmenulocation ) ){
        $locations = get_theme_mod('nav_menu_locations');
        $locations[$bpmenulocation] = $menu_id;
        set_theme_mod( 'nav_menu_locations', $locations );
    }

ฉันไม่รู้เกี่ยวกับฟังก์ชั่นนี้ ใช่ฉันเดาว่ามันจะทำให้โค้ดด้านบนสั้นลงมาก ฉันเดาว่าฉันควรจะย้ายเกิน Codex และดำดิ่งลงไปในรหัสจริงเนื่องจากฉันพบว่าฟังก์ชั่น API มักจะเหมือนในกรณีนี้ในระดับต่ำเกินไป ขอบคุณ!
julien_c

@julien_c ถ้าสิ่งนี้ได้รับการแก้ไขให้ทำเครื่องหมายเป็นเช่นนี้เพื่อให้ผู้ที่ติดตามคุณได้รับประโยชน์จากประสบการณ์ของคุณที่นี่
mor7ifer

ฉันแค่ต้องการทดสอบจริงในชีวิตจริงดังนั้นฉันแน่ใจว่ามันเป็นสิ่งที่ฉันต้องการ ฉันจะจำได้ว่าทำเครื่องหมายแก้ไขทันทีที่ฉันทำ!
julien_c

3
หากคุณเห็นฟังก์ชันที่มีประโยชน์เช่นนี้ที่ไม่ได้อยู่ใน codex คุณควรเพิ่ม (yay wiki) = p
Tom J Nowell

ขออภัยฉันใช้เวลานานมากในการตรวจสอบว่ามันใช้งานได้ในกรณีของฉัน ตอบรับแล้ว! นอกจากนี้คุณกำลังกำหนดรายการเมนูลิงก์ที่กำหนดเองฉันได้เพิ่มคำตอบด้านล่างเพื่อกำหนดลิงก์ของหน้าเว็บ (ซึ่งจะมีความแข็งแกร่งกว่าการเปลี่ยนแปลง URL เป็นต้น)
julien_c

12

ในฐานะที่เป็นส่วนเสริมของ Anwser ของ ZaMoose นี่คือวิธีที่คุณจะสร้างรายการเมนู" Page -type" (ไม่ใช่ " Custom "):

wp_update_nav_menu_item($menu_id, 0, array('menu-item-title' => 'About',
                                           'menu-item-object' => 'page',
                                           'menu-item-object-id' => get_page_by_path('about')->ID,
                                           'menu-item-type' => 'post_type',
                                           'menu-item-status' => 'publish'));

สมมติว่าคุณรู้ว่าตัวบุ้งหน้าเท่านั้น


9

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

อย่างแรกโค้ดด้านบนสร้างรายการนำทางประเภท "URL" ซึ่งใช้ได้สำหรับบางคน แต่ฉันต้องการเชื่อมโยงไปยังหน้าไม่ใช่ URL เพราะนี่เป็นคุณลักษณะที่สำคัญของการนำทาง WordPress และลูกค้าหลีกเลี่ยงสิ่งต่าง ๆ อย่างหลีกเลี่ยงไม่ได้ ประเภทรายการ nav

นอกจากนี้ยังมีการจัดการเด็ก ๆ ฉันได้สร้างฟังก์ชั่นสำหรับการประกาศรายการ nav ใหม่ซ้ำเก็บข้อมูลเมตากลับคืนของพวกเขา (ส่วนใหญ่ ID หลังจากที่ถูกสร้างขึ้นในวง) และพารามิเตอร์สำหรับการยอมรับเด็ก

เพียงแก้ไข$nav_items_to_addและจัดการส่วนที่เหลือซ้ำ มี 3 ปุ่มที่จำเป็นในแต่ละแถวลำดับ ครั้งแรกที่สำคัญอาร์เรย์เป็นกระสุนเพื่อให้เป็นสิ่งที่คุณต้องการสำหรับหน้าเว็บที่มีกระสุน 'shop' => array( ... ) เป็นวิธีที่รายการ nav จะมีป้ายกำกับที่ส่วนหน้า เป็นพา ธ ไปยังหน้าภายในลำดับชั้นของหน้า WordPress ดังนั้นนี่จะเหมือนกันกับตัวบุ้งถ้าหน้านั้นเป็นพาเรนต์ระดับบนสุดและหากเป็นลูกของมันจะเป็นเช่นนั้น shop['title']pathshophome'path' => 'home/shop'

คีย์อาร์เรย์ที่เป็นทางเลือกสุดท้ายคือ['parent']ที่ที่คุณสามารถประกาศคีย์อื่นในอาร์เรย์เป็นพาเรนต์ของคีย์ปัจจุบัน เป็นสิ่งสำคัญที่จะต้องทราบว่ารายการนั้นถูกเพิ่มซ้ำดังนั้นผู้ปกครองจะต้องมีอยู่ก่อนที่คุณจะพยายามสร้างเด็ก ซึ่งหมายความว่าการประกาศควรเกิดขึ้นสำหรับรายการ nav หลักก่อนเป็นรายการย่อย

    $locations = get_nav_menu_locations();

    if (isset($locations['primary_navigation'])) {
        $menu_id = $locations['primary_navigation'];

        $new_menu_obj = array();

        $nav_items_to_add = array(
                'shop' => array(
                    'title' => 'Shop',
                    'path' => 'shop',
                    ),
                'shop_l2' => array(
                    'title' => 'Shop',
                    'path' => 'shop',
                    'parent' => 'shop',
                    ),
                'cart' => array(
                    'title' => 'Cart',
                    'path' => 'shop/cart',
                    'parent' => 'shop',
                    ),
                'checkout' => array(
                    'title' => 'Checkout',
                    'path' => 'shop/checkout',
                    'parent' => 'shop',
                    ),
                'my-account' => array(
                    'title' => 'My Account',
                    'path' => 'shop/my-account',
                    'parent' => 'shop',
                    ),
                'lost-password' => array(
                    'title' => 'Lost Password',
                    'path' => 'shop/my-account/lost-password',
                    'parent' => 'my-account',
                    ),
                'edit-address' => array(
                    'title' => 'Edit My Address',
                    'path' => 'shop/my-account/edit-address',
                    'parent' => 'my-account',
                    ),
            );

    foreach ( $nav_items_to_add as $slug => $nav_item ) {
        $new_menu_obj[$slug] = array();
        if ( array_key_exists( 'parent', $nav_item ) )
            $new_menu_obj[$slug]['parent'] = $nav_item['parent'];
        $new_menu_obj[$slug]['id'] = wp_update_nav_menu_item($menu_id, 0,  array(
                'menu-item-title' => $nav_item['title'],
                'menu-item-object' => 'page',
                'menu-item-parent-id' => $new_menu_obj[ $nav_item['parent'] ]['id'],
                'menu-item-object-id' => get_page_by_path( $nav_item['path'] )->ID,
                'menu-item-type' => 'post_type',
                'menu-item-status' => 'publish')
        );
    }

    }

2

เพื่อเพิ่มรายการเมนูโดยทางโปรแกรม คุณสามารถขอwp_nav_menu_itemsกรอง วางรหัสด้านล่างในฟังก์ชั่นชุดรูปแบบของคุณ php เพื่อเพิ่มรายการเมนูเข้าสู่ระบบ / ออกจากระบบในเมนูหลัก 'หลัก' คือชื่อ / ID ของเมนูที่ลงทะเบียน

/**
 * Add login logout menu item in the main menu.
 * ===========================================
 */

add_filter( 'wp_nav_menu_items', 'lunchbox_add_loginout_link', 10, 2 );
function lunchbox_add_loginout_link( $items, $args ) {
    /**
     * If menu primary menu is set & user is logged in.
     */
    if ( is_user_logged_in() && $args->theme_location == 'primary' ) {
        $items .= '<li><a href="'. wp_logout_url() .'">Log Out</a></li>';
    }
    /**
     * Else display login menu item.
     */
    elseif ( !is_user_logged_in() && $args->theme_location == 'primary' ) {
        $items .= '<li><a href="'. site_url('wp-login.php') .'">Log In</a></li>';
    }
    return $items;
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.