Steve Taylor photo

Using WordPress 3.0 custom menus for custom stuff

The introduction of custom menus in WordPress 3.0 was very welcome. They can be a bit baffling at first (see the ever-reliable Justin Tadlock’s guide if you’re confused), but they’re a great CMS addition to WP.

Here I want to detail a couple of tips for going beyond the standard usage.

Just the list items, please

The function wp_nav_menu is the main interface exposed to the theme developer, and it’s nicely flexible. However, there doesn’t seem to be a way to omit the surrounding ul tags. The $container argument lets you control whether there’s surrounding div around the ul, but that’s it.

I have a situation with a footer menu where I want to hard-code a list item. The copyright needs to have some PHP to dynamically output the year, and AFAIK you can’t put PHP code into nav menu items. There’s probably other ways of doing this with filters, but here’s what I did: created a function to return the just the menu list items.

function slt_menuWithoutContainers( $menu ) {
	$menuItems = wp_nav_menu( array(
		'menu'	=> $menu,
		'container'	=> '',
		'echo'		=> false
	)  );
	return preg_replace( '/</?ul[^>]*>/i', '', $menuItems );
}

Just the post objects, please

I’m also seeing possibilities for situations that can’t strictly be described as menus. For instance, “featuring” items on the front page. On a site I’m working on there’s a custom post type (yeah, I’m really going to town on the 3.0 features) of “projects”, four of which have to be pulled up to feature in a scrolling jQuery thingy on the home page.

Usually I’d add a custom field checkbox—but what about ordering? The trusty My Page Order doesn’t hook into custom post types. How about using the menus system?

So, yes. Register and create a menu as per normal. Then, here’s some code to translate the menu into an array of post objects in the right order. It relies on a menu function buried in the core wp_get_nav_menu_items.

$slt_menuItems = wp_get_nav_menu_items( "[insert you menu name here]" );
$slt_postObjects = array();
foreach ( $slt_menuItems as $slt_menuItem )
	$slt_postObjects[] = get_post( $slt_menuItem->object_id );

Please bear in mind I’m creating this $slt_postObjects array to slot straight into some pre-existing code that, later on, loops through and expects an array of post objects. You could easily just do your outputting right here in the loop through $slt_menuItems—and also take advantage of things like the menu item title, which could be different from the post title.

I think this could be improved. Maybe there’s a more efficient way of gathering the post data than using get_post over and over? AFAIK we can’t use get_posts and the $include argument, because if you’re using custom post types, there’s no easy way to adjust and use menu_order. Any ideas? Answers on a postcard please! (Or just in the comments here.)

2 comments

  1. ..just a note, remember that you can use these wordpress menu examples in older templates as well, but you will have to replace the navigation functions in the template files with these new wordpress 3 menu functions – many people dont realize it even though its the obvious thing to do.

  2. Simon Foxe avatar Simon Foxe

    Fantastic post! You really saved me with this one. I’d been searching for hours for assistance in creating my own menu structure with static items (as required by the client).

    Your idea for using a Menu to order and display custom post types is also fantastic, though you may also want to check out the plugin ‘Post Types Order’ by NSP CODE as a possible alternative.

    Keep up the great work and thanks for sharing

Leave a comment

Your email address will not be published. Required fields are marked *

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>