Through API functions, I want to define a new Navigation menu, select it in the current theme, and then insert a few Pages as menu items. This is to be done for instance on a theme activation.
Through a (moderately painful) process of reverse engineering the database inserts and updates after manually setting up the Navigation menu and items, I’ve pieced together the following steps, where ‘footer-nav’ is the slug ID of the Navigation menu I’m creating:
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');
}
This seems to work, but:
- is it a robust and elegant way of doing it?
- am I missing something totally obvious that would do all this in one line of code?
I might be misunderstanding you, but why not use wp_create_nav_menu()
?
E.g., this is what I do to create a custom BuddyPress menu when I detect BP as active:
$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( "https://wordpress.stackexchange.com/" ),
'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 );
}