Creating Menu in WordPress 3.0 Programmatically

WordPress

WordPress 3.0 has been around for a while. One of its great features is the menu system. We can use the menu system out of the box from the WordPress administration screen. From there we can create a menu with flexible menu item configuration. The menu item can be configured to point and open specific post or page, specific category or tag, or custom URL. The good news for programmers: all of those things can be done programmatically. You can create a menu and its all configurable menu items via PHP code. This post will shows you some example on how to do it.

Maybe you are wondering and asking when we will need to create a WordPress menu programmatically. Admitted, there should be not so many requirements to create a menu programmatically. But I found one feasible usage: we can create a menu on the fly upon an activation of a plugin. If you are a plugin writer, you should already know that plugins have activation event. In this activation event, we can create anything: database tables, posts, pages, categories, tags, and of course the menu. This is of course assuming that the plugin needs to create those items to support its function, not just arbitrarily.

OK, now let me just jump into the sample code of creating a WordPress menu programmatically. First task is creating the menu itself. The source code below shows you an example of creating a new empty menu in WordPress 3.0:

$menu_id = wp_create_nav_menu('My Menu', array('slug' => 'my-menu'));

Second task is creating menu items programmatically. Here is a sample of a menu item that points to specific page. When the menu is clicked, the page will be opened and become active:

$post_id = wp_insert_post(array('post_title' => 'My Post', 'post_type' => 'page'));
wp_update_nav_menu_item(
  $menu_id,
  0,
  array(
	 'menu-item-title' => 'My Menu',
	 'menu-item-type' => 'post_type',
	 'menu-item-object' => 'post',
	 'menu-item-object-id' => $post_id,
	 'menu-item-position' => 1,
	 'menu-item-status' => 'publish')
  );

Here is some explanation of the code above:

  • To create a new menu item, put 0 as the second parameter value in wp_update_nav_menu_item function call.
  • To point to specific post or page (or custom post_type), use 'menu-item-type' => 'post_type'
  • We have to know the id of the post or page to be assigned to the menu item, so in the sample code above I created a new post on the fly, get its id and assign it to the menu item. We can also retrieve existing post or page based on title or slug to get its id.

If you need the menu item to point to category or tag archive, the following source code shows an example on how to do it:

$term_id = wp_insert_category(array('cat_name' => 'My Category'));
wp_update_nav_menu_item(
   $menu_id,
   0,
   array(
      'menu-item-title' => 'My Menu',
      'menu-item-type' => 'taxonomy',
      'menu-item-object' => 'category',
      'menu-item-object-id' => $term_id,
      'menu-item-position' => 1,
      'menu-item-status' => 'publish')
 );

Note how menu-item-type and menu-item-object are different from the previous sample code. Finally, to point to specific URL, we can create a ‘custom’ menu item, as shown in the following source code:

wp_update_nav_menu_item(
   $menu_id,
   0,
   array(
      'menu-item-title' => 'My Menu',
      'menu-item-type' => 'custom',
      'menu-item-url' => '../',
      'menu-item-position' => 1,
      'menu-item-status' => 'publish')
 );

So, now we already have the menu with all its item. The third and final task is to assign the menu to a ‘theme location’. A ‘theme location’ is a concept introduced by WordPress 3.0. It is a location where we can display the menu. Theme location must be registered by theme we are using. If we use standard ‘Twenty Ten’ theme, there is a registered navigation location called ‘primary’.

The responsibility of assigning a menu into ‘theme location’ does NOT belong to navigation menu API. It is theme option. The following code shows how we can configure theme option to assign the menu we created before to a registered theme location:

$theme = get_current_theme();
$mods = get_option("mods_$theme");
$key = key($mods['nav_menu_locations']);
$mods['nav_menu_locations'][$key] = $menu_id;
update_option("mods_$theme", $mods);

OK, that’s all what I can give folks. I hope now you understand how to create a menu and menu items programmatically in WordPress 3.0.

This entry was posted in WordPress and tagged .

7 Responses to Creating Menu in WordPress 3.0 Programmatically

  1. Jason says:

    Thanks for this. I was tripping over myself trying to find a solution to the same problem.

  2. Pingback: wp-popular.com » Blog Archive » Creating Menu in WordPress 3.0 Programmatically « suhanto.net

  3. Steve says:

    Tried installling your code and I’m receiving an error:
    “Warning: key() [function.key]: Passed variable is not an array or object in functions.php on line 266″

    line 266 is: $key = key($mods['nav_menu_locations']);

    Any ideas?

    I would really appreciate your help.

    Thanks
    Steve

  4. This is fantastic! Just what I had been looking for! Thanks!

    I took a slightly different approach, though… Instead of using ‘theme location’, I just use the ‘menu’ parameter to determine the location of the menu.

    In functions.php:

    $menu_id = wp_create_nav_menu(‘Main Menu’, array(‘slug’ => ‘main-menu’));

    wp_update_nav_menu_item(
    $menu_id,
    0,
    array(
    ‘menu-item-title’ => __(‘Home’),
    ‘menu-item-type’ => ‘custom’,
    ‘menu-item-url’ => ‘http://’,
    ‘menu-item-position’ => 1,
    ‘menu-item-status’ => ‘publish’
    )
    );

    In the theme template (eg. header.php), I just put the following lines where the menu should be:

    ‘Main Menu’ ) ); ?>

    This way, I don’t have to register any theme location.

  5. SR says:

    This is great, thanks! Very helpful. Question – how do you create menu relationships? How do you programmatically set one menu item to be the parent or child of another? Thanks!

Leave a Reply

Your email address will not be published.

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

About Me

I am a professional developer and designer for the following systems: WordPress, Magento, and OpenCart. You can hire me to do overseas works related to those systems.
Hire me | Donate / Payment | Testimonials

Recent Comments