Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

Is there any way that i can hard code the custom menu items when first theme installed? I am creating a theme which will automatically make some common pages when installed. So I need to know if I can also add them to Wordpress custom menu so client don't need to add them manually?

In other words: how to insert/create custom menu item programmatically?

Let me know if anything unclear. Guide to the appropriate codex page is welcome. Thanks!


update: tried code from here Targeting specific menu with wp_nav_menu_items

Menu registration:

function register_my_menus() {
  register_nav_menus(
    array('main-menu' => __( 'Main Menu' ) )
  );
}

add_action( 'init', 'register_my_menus' );

Template use:

<?php wp_nav_menu( array( 'theme_location' => 'main-menu' ) ); ?>

Code for adding new items:

function new_nav_menu_items($items) {
    if( $args->theme_location == 'main-menu' ){
    $homelink = '<li class="home"><a href="' . home_url( '/' ) . '">' . __('Home') . '</a></li>';
    $items = $homelink . $items;
    return $items;
    }
}
add_filter( 'wp_nav_menu_items', 'new_nav_menu_items', 10, 2 );

when adding the code for adding new items in nav menu in functions.php file nothings happens in menu page in admin panel but the current menu items are gone in site!

share|improve this question

4 Answers 4

up vote 16 down vote accepted

The Problem with your code is that its not actually adding the links to the menu and only to the menu's output, hence the use of a filter (add_filter) so you are just filtering the output of the menu in fact even if you don't have a menu your link will be shown with the code you are using. But to create a link and add it to a menu you can use this code:

$run_once = get_option('menu_check');
if (!$run_once){
    //give your menu a name
    $name = 'theme default menu';
    //create the menu
    $menu_id = wp_create_nav_menu($name);
    //then get the menu object by its name
    $menu = get_term_by( 'name', $name, 'nav_menu' );

    //then add the actuall link/ menu item and you do this for each item you want to add
    wp_update_nav_menu_item($menu->term_id, 0, array(
        'menu-item-title' =>  __('Home'),
        'menu-item-classes' => 'home',
        'menu-item-url' => home_url( '/' ), 
        'menu-item-status' => 'publish'));

    //then you set the wanted theme  location
    $locations = get_theme_mod('nav_menu_locations');
    $locations['main-menu'] = $menu->term_id;
    set_theme_mod( 'nav_menu_locations', $locations );

    // then update the menu_check option to make sure this code only runs once
    update_option('menu_check', true);
}

I commented all over to make it simpler.

To create a child page/sub page/second level menu (how ever you may call it), you just need to set the menu-item-parent-id in the new item for example:

//create the top level menu item (home)
$top_menu = wp_update_nav_menu_item($menu->term_id, 0, array( 
    'menu-item-title' =>  __('Home'),
    'menu-item-classes' => 'home',
    'menu-item-url' => home_url( '/' ), 
    'menu-item-status' => 'publish'
    'menu-item-parent-id' => 0,
    ));
//Sub menu item (first child)
$first_child = wp_update_nav_menu_item($menu->term_id, 0, array( 
    'menu-item-title' =>  __('First_Child'),
    'menu-item-classes' => 'home',
    'menu-item-url' => home_url( '/' ), 
    'menu-item-status' => 'publish'
    'menu-item-parent-id' => $top_menu,
    ));
//Sub Sub menu item (first child)
$Second_child = wp_update_nav_menu_item($menu->term_id, 0, array( 
    'menu-item-title' =>  __('Second_Child'),
    'menu-item-classes' => 'home',
    'menu-item-url' => home_url( '/' ), 
    'menu-item-status' => 'publish'
    'menu-item-parent-id' => $first_child,
    ));

also you can set the position by code with menu-item-position and i think its done like this:

  • First item - 'menu-item-position' => 1
    • First item first child - 'menu-item-position' => 1
    • First item second child - 'menu-item-position' => 1
      • First item second child first child - 'menu-item-position' => 1
  • Second item - 'menu-item-position' => 2
  • 3rd item - 'menu-item-position' => 3
  • 4th item - 'menu-item-position' => 4
share|improve this answer
    
Those are the functions i was looking for :) codex does not included these :( One more question how can i add a item child to the Home item. I will let you know as soon as i get to my pc. Thanks! –  Sisir Apr 24 '11 at 17:42
    
@Sisir: i updated with an example how to create child pages –  Bainternet Apr 25 '11 at 0:12
    
@Bainternet: got this error when first run the code Fatal error: Cannot use object of type stdClass as array in C:\wamp\www\citystir\wp-admin\menu.php on line 25. But the menu is get created and when page refreshed everything works but nothing is showing in Appearance -> Menu Theme Location section. We are really close :) Thanks! –  Sisir Apr 28 '11 at 19:36
    
@Bainternet: My guess is the code is getting error when it trying to run the code $locations = get_theme_mod('nav_menu_locations'); So, the codes before that (all the menu insertion is done) get executed and code after that (set the wanted theme location) don't get executed. –  Sisir Apr 28 '11 at 19:48
    
@Sisir: code is working just fine, what is your theme location name and show me the exact code you are using , i'll see if i can help. –  Bainternet Apr 29 '11 at 0:26

Your original code is very close to the money and I seriously think the this long solution by @Bainternet (no offence) is overkill, so have a look at this instead:

function new_nav_menu_items($items, $args) {
    if( $args->theme_location == 'primary' ){
        $homelink = '<li class="home"><a href="' . home_url( '/' ) . '">' . __('Home') . '</a></li>';
        $items = $homelink . $items;
    }
    return $items;
}
add_filter( 'wp_nav_menu_items', 'new_nav_menu_items', 10, 2 );

Your only problem was that you were not returning $items after the function checked for the correct menu, and you were missing the second callback argument that was needed to make the check ($args).

share|improve this answer

In Wordpress 3.4.2 is bug https://github.com/WordPress/WordPress/commit/ae96b842f9f55ecfb22da705a4902b9d25580259#wp-includes/nav-menu.php

You need create term relation manually:

$menu = wp_get_nav_menu_object('top menu');
$id = wp_update_nav_menu_item($menu->term_id, 0, $data);

if ($menu->term_id && (!is_object_in_term($id, 'nav_menu', (int)$menu->term_id))) {
    wp_set_post_terms($id, array((int)$this->id), 'nav_menu');
}

https://gist.github.com/4148529 - example of Menu class for simple menu creation

share|improve this answer

For information, current user has to got rights to add terms, my menu_items were created but not added in the table wp_terms_relationship before I add a call to wp_set_current_user(1);

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.