Programlı bir Navigasyon menüsü ve menü öğeleri ekleyin


41

API işlevleriyle yeni bir Gezinti menüsü tanımlamak , geçerli temada seçmek ve ardından menü öğeleri olarak birkaç Sayfa eklemek istiyorum. Bu, örneğin bir tema aktivasyonu için yapılmalıdır.

Navigasyon menüsünü ve öğelerini manuel olarak ayarladıktan sonra veritabanı (orta derecede ağrılı) bir tersine mühendislik süreci sayesinde veritabanı ekler ve günceller. m oluşturma:

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

Bu iş gibi görünüyor, ama:

  • Bunu yapmanın sağlam ve zarif bir yolu var mı?
  • Bütün bunları tek bir kod satırında yapacak olan açık bir şeyi mi kaçırıyorum?

Yanıtlar:


42

Seni yanlış anlıyor olabilirim ama neden kullanmıyorsun wp_create_nav_menu()?

Örneğin, BP'yi aktif olarak algıladığımda özel bir BuddyPress menüsü oluşturmak için yaptığım şey:

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

Bu işlevi bilmiyordum. Evet, yukarıdaki kodu daha kısa hale getireceğini tahmin ediyorum. Sanırım, API işlevlerinin sık sık, bu durumda olduğu gibi, çok düşük seviyeli olduğunu fark ettiğim için Kodeks'in ötesine geçmeli ve gerçek koda dalmalıyım. Teşekkürler!
julien_c

@julien_c eğer bu çözülürse, sizden sonra gelenlerin buradaki deneyiminizden faydalanmalarını sağlamak için işaretleyin.
mor7ifer

Sadece gerçek hayatta test etmek istiyorum, bu yüzden istediğimi yaptığına eminim. İşim biter bitmez çözülmüş olarak işaretlemeyi hatırlayacağım!
julien_c

3
Kodeks'te olmayanlar gibi yararlı fonksiyonlar görürseniz, bunları eklemek iyi bir fikirdir (yay wiki) = p
Tom J Nowell

Üzgünüm, benim davamda çalıştığını kontrol etmek çok uzun sürdü. Cevap kabul edildi! Ayrıca, özel bağlantılar menü öğelerini tanımlıyorsunuz, sayfa bağlantılarını tanımlamak için aşağıya bir cevap ekledim (örneğin, URL değişikliklerinde daha sağlam olacak).
julien_c

12

ZaMoose'un cevabının bir tamamlayıcısı olarak, nasıl bir " Sayfa tipi" menü öğesi (" Özel " bir tane değil) oluşturacağınız:

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

Örneğin sayfa çıktısını bildiğinizi varsayalım.


9

Kabul edilen cevabımla ilgili birkaç sorunum var - bu yanlış yapmaz, ancak aynı soruyu yaptığımdan ancak bazılarını daha iyi sonuç verebileceğini düşündüğüm kendi kodumu aşağıya yazacağım. daha az kodlu bir şey.

İlk olarak, yukarıdaki kod, bazı insanlar için iyi olan "URL" türü gezinme öğeleri oluşturur; ancak bu, WordPress gezilerinin önemli bir özelliği olduğundan ve URL'leri bağlamak istediğim için URL'lere bağlanmak istiyorum, URL'leri asla kullanmamalıyım. nav öğe türü.

Ayrıca, yalnızca düz bir çocuk dizisi postalanan kod tarafından ele alınır. Yeni nav öğelerini yinelemeli olarak bildirmek, döndürülen meta verilerini (çoğunlukla döngüde oluşturulduktan sonra ID) saklamak ve çocukları kabul etmek için bir parametre oluşturmak için bir işlev oluşturdum.

Sadece düzenleme yapın $nav_items_to_addve geri kalanlar özyinelemeyle ele alınır. Her dizide 3 gerekli anahtar vardır. İlk olarak, dizi anahtarı sümüklü böcek, yani 'shop' => array( ... )sümüklü böcek içeren bir sayfa için istediğiniz şeydir shop. ['title']nav öğesinin ön ucunda etiketlenme şeklidir. pathsayfa bir üst düzey ebeveyn ise bu sümüklü böcek aynıdır ve eğer öyleyse WordPress sayfası hiyerarşisi içinde sayfasının yolu vardır shopbir çocuktun homeo zaman olurdu 'path' => 'home/shop'.

Son isteğe bağlı dizi anahtarı, dizideki ['parent']başka bir anahtarı geçerli anahtarın ebeveyni olarak bildirebileceğiniz yerdir. Maddelerin özyinelemeli olarak eklendiğini not etmek önemlidir, bu nedenle bir çocuk yaratmaya çalışmadan önce ebeveynin var olması gerekir. Bu, ilanın çocuklanmadan önce ana nav öğe için yapılması gerektiği anlamına gelir.

    $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

Programlı olarak bir menü öğesi eklemek için. wp_nav_menu_itemsfiltrelemek için kanca olabilir . Ana menüde login / logout menü maddesi eklemek için, functions.php içindeki kodun altına yerleştirin. 'Birincil' kayıtlı menünün adı / kimliğidir.

/**
 * 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;
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.