Secara terprogram tambahkan menu Navigasi dan item menu

41

Melalui fungsi API, saya ingin menentukan menu Navigasi baru , memilihnya dalam tema saat ini, dan kemudian menyisipkan beberapa Halaman sebagai item menu. Ini harus dilakukan misalnya pada aktivasi tema.

Melalui proses (yang cukup menyakitkan) dari rekayasa balik database menyisipkan dan memperbarui setelah secara manual mengatur menu Navigasi dan item, saya telah menyatukan langkah-langkah berikut, di mana 'footer-nav' adalah slug ID dari menu Navigasi I ' m membuat:

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

Ini tampaknya berhasil, tetapi:

  • apakah ini cara yang kuat dan elegan untuk melakukannya?
  • Apakah saya kehilangan sesuatu yang sangat jelas yang akan melakukan semua ini dalam satu baris kode?
julien_c
sumber

Jawaban:

43

Saya mungkin salah paham dengan Anda, tetapi mengapa tidak menggunakannya wp_create_nav_menu()?

Misalnya, ini yang saya lakukan untuk membuat menu BuddyPress khusus ketika saya mendeteksi BP sebagai aktif:

    $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 );
    }
ZaMoose
sumber
Saya tidak tahu tentang fungsi ini. Ya, saya kira itu akan membuat kode di atas jauh lebih pendek. Saya kira saya harus bergerak di luar Codex dan masuk ke kode yang sebenarnya, karena saya menemukan bahwa fungsi API sering, seperti dalam kasus ini, terlalu rendah level. Terima kasih!
julien_c
@julien_c jika ini diselesaikan, tandai sedemikian rupa untuk memungkinkan mereka yang datang setelah Anda mendapatkan manfaat dari pengalaman Anda di sini.
mor7ifer
Saya hanya ingin benar-benar mengujinya dalam kehidupan nyata jadi saya yakin itu melakukan apa yang saya inginkan. Saya akan ingat untuk menandainya selesai setelah saya selesai!
julien_c
3
Jika Anda melihat fungsi-fungsi bermanfaat seperti ini yang tidak ada dalam kodeks, adalah ide yang baik untuk menambahkannya (yay wiki) = p
Tom J Nowell
Maaf saya butuh waktu lama untuk memeriksa apakah itu berhasil dalam kasus saya. Jawaban diterima! Selain itu, Anda mendefinisikan item menu tautan kustom , saya telah menambahkan jawaban di bawah ini untuk menetapkan tautan halaman (yang akan lebih kuat untuk perubahan URL, misalnya).
julien_c
12

Sebagai pelengkap anwser ZaMoose, berikut ini cara membuat item menu " Halaman- jenis" (bukan item " Ubahsuaian "):

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'));

Misalnya Anda hanya tahu halaman slug, misalnya.

julien_c
sumber
9

Saya memiliki beberapa masalah dengan jawaban yang diterima - itu tidak membuatnya salah, tetapi saya akan memposting kode saya sendiri di bawah ini yang saya rasa mungkin memiliki hasil yang lebih baik untuk beberapa orang karena saya memiliki pertanyaan yang sama tetapi ingin melakukan hal yang sama hal dengan kode lebih sedikit.

Pertama, kode di atas membuat item navigasi jenis "URL", yang baik untuk beberapa orang, tetapi saya ingin menautkan ke PAGES, bukan URL karena ini adalah fitur penting dari navigasi WordPress dan klien dapat memindahkan hal-hal yang tidak terhindarkan sehingga saya tidak pernah menggunakan URL jenis item nav.

Juga, hanya sejumlah kecil anak-anak yang ditangani oleh kode yang diposting. Saya telah membuat fungsi untuk mendeklarasikan item nav baru secara rekursif, menyimpan metadata mereka yang dikembalikan (terutama ID setelah dibuat dalam loop), dan parameter untuk menerima anak-anak.

Cukup edit $nav_items_to_adddan sisanya ditangani secara rekursif. Ada 3 kunci yang diperlukan di setiap array. Pertama, kunci array adalah siput, demikian 'shop' => array( ... )juga yang Anda inginkan untuk halaman dengan siput shop. ['title']adalah cara item nav akan dilabeli di ujung depan. pathadalah jalur ke halaman dalam hierarki halaman WordPress, jadi ini identik dengan siput jika halaman tersebut adalah induk level atas, dan jika shopmasih anak-anak homemaka itu akan menjadi 'path' => 'home/shop'.

Kunci array opsional terakhir adalah ['parent']tempat Anda dapat mendeklarasikan kunci lain dalam array sebagai induk dari kunci saat ini. Penting untuk dicatat bahwa item ditambahkan secara rekursif, sehingga orang tua harus ada sebelum Anda mencoba membuat anak. Ini berarti deklarasi harus terjadi untuk item nav induk sebelum anak-anaknya.

    $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')
        );
    }

    }
Brian
sumber
2

Untuk menambahkan item menu Secara terprogram. Anda dapat menghubungkan ke wp_nav_menu_itemsfilter. letakkan kode di bawah ini di dalam functions.php tema Anda untuk menambahkan item menu login / logout di menu utama. 'Utama' adalah nama / id dari menu yang terdaftar.

/**
 * 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;
}
Aamer Shahzad
sumber