Adding Class To The WordPress Page Menu

Problem: You need to add a class or id to the the unordered list in wp_page_menu. Maybe to implement some super-slick drop down page menus. But! That <ul> tag is trapped inside of wp_page_menu. What are you going to do?

Solution: Filter wp_page_menu. In the code example below we’ll use preg_replace to find the first—and only the first—<ul> tag and swap it out for <ul id="nav" class="something-classy">. Just drop this code snippet into your theme’s functions.php file and you’re set.

// Add ID and CLASS attributes to the first <ul> occurence in wp_page_menu
function add_menuclass( $ulclass ) {
  return preg_replace( '/<ul>/', '<ul id="nav" class="something-classy">', $ulclass, 1 );
}
add_filter( 'wp_page_menu', 'add_menuclass' );

22 responses

  1. […] How to add class to wp_page_menu […]

  2. I swear I have been searching the net all day today for something like this. I am not the greatest at PHP, but know there was some way to create a class menu inside wp_page_menu for 2.7, I mean 2.7.1.

    Maybe know I can find a good jQuery animation to apply for a nifty drop down menu.. Cheers!

  3. Oh, so am I to assume that if I replace 1 with 2 I could add an ID to a child ul?

    1. I haven’t tried it but give it a shot. I know you can do loops with replace functions too. That might be worth trying.

      1. I tried it out and it worked, I had to write up a new function, and change some text:

        function add_sub_menuclass($ulchildclass) {
        	return preg_replace('/<ul>/', '<div><ul>', $ulchildclass, 1);
        }

        but not sure how to apply it to all the child lists, only way is to change the number to the ammont of ul‘s you want to change (like if you had 4 child lists, change the 1 to a 4) It will count how ever many ul lists.

    2. To add the class to all the child elements within the list. Just replace 1 with -1 (signifies no limit). But make sure to remove the id=”nav” as it will violate the xhtml standards if the same id is given to all the child lists

  4. oops, may want to apply and overflow on your pre..

  5. This seems like a very elegant solution.

    I would like to figure out how to change this solution to add a class to only the ‘contact’ list item in the menu. Would this be easy to do?

  6. […] Word Cloud dell’articolo Articolo pubblicato da Ian Stewart su Themeshaper. […]

  7. […] im Output unseres Seitenmenüs und erweitern diesen um eine ID und eine Klasse. Ian Steward von ThemeShaper hat diese Lösung […]

  8. So I’ve linked to this from WPLover but completely forgot it. Glad to find this now, right when I need it. Thanks Ian!

  9. Suzanne Avatar

    Ian I found you today in my quest for what, I forgot, but the reason I forgot is due to the fact that you, your site and all your great info catapulted me as a theme developer into the next dimension. Funny how you stumble upon things just as you’re most ready for them.

    This little tidbit in this post is another tool in my arsenal. Thanks a ton and keep up the great work.

    – New Fan Suzanne

  10. Or alternatively you can use the built-in WordPress functionality by passing a class to the surround div.

    When passing via array:
    'menu_class' => 'something-classy',
    When passing via query string:
    &menu_class=something-classy

    Then you css styling requires only
    .wp_page_menu .something-classy ul

    1. Ooppss! No edit button for comments. CSS would be:


      ul.something-classy {
      blah blah
      }

      1. I thought menu_class just affected the surrounding div.

  11. […] Ian Stewart has written a nice post on how to add a class or id to the list through a WordPress filter. […]

  12. Is there a way to apply this to parent pages only? I’m looking to add a small down arrow via a class to let the user know there are drop down items.

  13. […] Ian Stewart has written a nice post on how to add a class or id to the list through a WordPress filter. […]

  14. I’ve successfully added a class to the first ul in wp_page_menu,
    however I can’t seem to add a class to the child ul nested inside the first li.
    Here’s my code – can you see what it’s missing?

    function add_menuclass($ulclass) {
    return preg_replace('//', '', $ulclass, 1);
    }
    function add_sub_menuclass($ulchildclass) {
    return preg_replace('//', '', $ulchildclass, 2);
    }
    add_filter('wp_page_menu','add_menuclass','add_sub_menuclass');

  15. Thanks for the great info. helped me big time. For those, like me, who wish to add something to the last can use this code, it will replace the last occurrence of ul

    function add_sub_menuclass($ulchildclass) {
    return preg_replace('%(?!.*.*)%', '', $ulchildclass );
    }
    add_filter('wp_page_menu','add_sub_menuclass');

    similarly, for adding a class to last for formatting purpose, you can use
    function add_li_menuclass($lichildclass) {
    return preg_replace('%<li class="(?!.*<li class=".*)%', '<li class="last_item ', $lichildclass );
    }
    add_filter('wp_page_menu','add_li_menuclass');

    I hope it helps, it surely helped me manage the look.

    1. (sorry, I posted my reply on the wrong comment. This is the right one).

      This doesn’t seem to work in WP 3.0. I am trying to add a’first and ‘last’ class to my primary nav list and it isn’t showing up. I think you need to filter something other than wp_page_menu in thematic. Would that be wp_nav_menu and will the code still work as written above? I just tried it in WP 3.0.1 using thematic 0.9.7.7, and it didn’t work. Are there any thematic related snippets out there that can help me with this?
      Thanks in advance