How to Remove the <ul> container with the wp_nav_menu function

Although WordPress has an option to remove the container from the wp_nav_menu function, that is generally for the <div> and not the <ul> that wraps the <li> items. So, while you can use the options to remove the <div>, the <ul> will stay. It might be good to use a filter method like add_filter( ‘wp_nav_menu’, ‘remove_ul’ ) to accomplish the filter I have below, but that the filter was not being applied at the time of writing, so I (used to) recommend changing the echo option to false, and returning the value of the wp_nav_menu function to a variable, and then running a regular expression on it to remove the encompassing </ul><ul> and </ul>.

This code worked for me, running WordPress 3.0.4:

$options = array(
  'echo' => false
  ,'container' => false
);
$menu = wp_nav_menu($options);
echo preg_replace( array( '#^<ul [^>]*>#', '#</ul>$#' ), '', $menu );

Use Site Pages as a Default Fallback

If you want it to use the site’s pages as a default (if no menu is specified and the function is called), you can add an additional function and change the options array as shown:

function default_page_menu() {
   wp_list_pages('title_li=');
}
$options = array(
  'echo' => false
  ,'container' => false
  ,'fallback_cb'=> 'default_page_menu'
);
$menu = wp_nav_menu($options);
echo preg_replace( array( '#^<ul [^>]*>#', '#</ul>$#' ), '', $menu );

Update: A Better Way to Remove the <ul> element

I think as of WordPress 3.1 they added a new parameter to make it easier to get rid of the </ul><ul> that wraps the menu. It is called items_wrap

When you call wp_nav_menu you will want to specify that option.

By default it is set as:

'items_wrap' => '</ul><ul id=\"%1$s\" class=\"%2$s\">%3$s</ul>'

To get the ul to go away change it to:

'items_wrap'=>'%3$s'

Also, someone had a question about changing the <li> elements to <divs>. I would recommend doing this with CSS instead (i.e. just set them to display as blocks), but if really want to do that you might want to use a regular expression like this:

$menu_items = preg_replace('#<li #','<div',$menu_items);
$menu_items = preg_replace('#/li>#','/div>',$menu_items);

Or use a menu walking function like the one described on this page. How To Remove The Lt Ul Gt Container With The Wp Nav Menu Function

Related Posts:

This entry was posted in Tech Tips, Web Development and tagged , . Bookmark the permalink.

9 Responses to How to Remove the <ul> container with the wp_nav_menu function

  1. Sasha Evdakov says:

    Super awesome post – most helpful ever. Thank you – This solved my problem!

  2. Luke Etheridge says:

    Absolutely spot on! tips hat

  3. Sinac says:

    Hi, if want to replace ul with table ,what to do? I think … echo preg_replace( array( ‘#^]>#’, ‘#$#’ ), array( ‘#^]>#’, ‘#$#’ ), $menu ); But it’s not work. Please help me, thanks

  4. Geoff Rogers says:

    Thanks for posting – I’ve been looking for a fix for this!

  5. Andrei Gonzales says:

    Is there a way to remove ul and replace the li’s with individual divs?

  6. Will says:

    Bob, thanks for the note. I’ve updated my post to include your valuable addition! :)

  7. Bob says:

    I have asked a long question on stack exchange

    :)

  8. Cameron says:

    Yep I was looking for just this fix too! I had my Walker_Nav_Menu class all set up to spit out my own custom formatting but it kept on getting that damn <ul> in there!

    Thanks a bunch!

  9. Bob says:

    Thanks for this. It’s really removed bullet in my head :)

Leave a Reply

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>