問題描述
通過 API 函數,我想定義一個新的 Navigation menu,在當前主題中選擇它,然後插入幾頁作為菜單項。例如在主題激活時可以進行這種操作。
通過手動設置導航菜單和項目後,通過逆向工程數據庫插入和更新 (中等痛苦) 的過程,我將以下步驟拼接在一起,其中’footer-nav’ 是我正在創建的導航菜單的插槽 ID:
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');
}
這似乎有效,但是
- 這是一個強大而優雅的做法嗎?
- 我缺少一個完全明顯的代碼,可以在一行代碼中完成所有這些操作
最佳解決方案
我可能會誤會你,但為什麼不用 wp_create_nav_menu()?
例如,當我檢測到 BP 為活動時,這就是我創建一個自定義 BuddyPress 菜單:
$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 的一個補充,下面是如何創建”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'));
假設你只知道頁面插塊,例如。
第三種解決方案
我有一些接受的答案的問題 – 這不是錯的,但我會發布我自己的代碼在下面,我覺得可能會有一些更好的結果,因為我有同樣的問題,但想做同樣的少代碼的東西
首先,上面的代碼創建了”URL” 類型的導航項,這對於某些人來説很好,但是我想鏈接到 PAGES,而不是 URL,因為這是 WordPress 導航和客户端的一個重要功能,所以不可避免地會移動它,所以我從來沒有使用 URL 導航項類型。
此外,只有一個平面的孩子數組由發佈的代碼處理。我創建了一個遞歸聲明新的導航項目的函數,存儲返回的元數據 (主要是在循環中創建的 ID),以及接受子項的參數。
只需編輯 $nav_items_to_add,其餘的就是遞歸處理。每個陣列中有 3 個必需的鍵。首先,數組鍵是 s 子,所以'shop' => array( ... )是你想要的一個頁面與 s 子 shop 。 ['title']是導航項目在前端標記的方式。 path 是 WordPress 頁面層次結構中頁面的路徑,所以如果該頁面是 top-level 父項,則與 Slug 相同,如果 shop 是 home 的子代,那麼它將是'path' => 'home/shop'。
最後一個可選數組鍵是 ['parent'],您可以在數組中聲明另一個鍵作為當前的另一個鍵。重要的是要注意,這些項目是遞歸地添加的,因此在嘗試創建子項之前,父項必須存在。這意味着聲明應該在父導航項目在孩子之前發生。
$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')
);
}
}
參考文獻
注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。