WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm trying to find a way that changes the classes of the different nav menu items, based on the value of a meta key in the page.

The menu currently looks like this:

<li class="menu-item-1">Menu item 1</li>
<li class="menu-item-2">Menu item 2</li>
<li class="menu-item-3">Menu item 3</li>
<li class="menu-item-4">Menu item 4</li>
<li class="menu-item-5">Menu item 5</li>

Using custom keys I want to fetch the individual key from each page and put them in the corresponding menu item, as a class like:

<li class="menu-item-1 pink">Menu item 1</li>
<li class="menu-item-2 yellow">Menu item 2</li>
<li class="menu-item-3 green">Menu item 3</li>
<li class="menu-item-4 pink">Menu item 4</li>
<li class="menu-item-5 bordeaux">Menu item 5</li>

This is what I've got so far:

add_filter('nav_menu_css_class' , 'special_nav_class' , 10 , 2);
function special_nav_class($classes, $item){
    global $post;
    $colorcode = get_post_meta($post->ID, 'color_dropdown', true);
    if(is_page()) {
        $classes[] = $colorcode;
    return $classes;

What it does is that it adds the meta key to the classes, but only when visiting the page that has a meta key value assigned, and then it adds it to all menu items, which is not right.

I cannot fall back to the menu editor manually using the CSS class feature. The user won't be having access to that area, and it's crucial that the user can set the different classes via a metabox dropdown menu in the actual page edit mode.

Been pulling my hair for a while now, and I can't seem to get it to work, is it impossible?


share|improve this question
Your example works, are you sure the meta key is in the page and the nav menu is setup? – ampt May 4 '12 at 0:59
@ampt Really? If I write test $classes[] = 'test'; instead of $colorcode, I get "test" on every page menu item. If I do a var_dump(get_post_meta($post->ID, 'color_dropdown', true)); I just get back empty strings. I'm 100% certain that one of the pages have a value assigned to color_dropdown. First I thought it was an issue with the Roots Framework I'm using, but it doesn't seem to be because of that. I'm using Wordpress 3.1.3 if that could impede in someway? – INT May 4 '12 at 9:32
@ampt Ok, now I see. If I visit the actual page that has the meta key, it shows up, but I need the meta key as a class at all times (some menu items should be red, some green etc). – INT May 4 '12 at 10:03
up vote 1 down vote accepted

Your code doesn't because the global $post refers to the post/page being viewed (if there is one...). What is passed with nav_menu_css_class is a menu item - this is a particular post type. Among its properties are: object which stores:

  • the post type if the link refers to a post
  • the taxonomy if the link refers to a taxonomy-term page
  • 'custom' if its a custom link

It also stores the object_id

  • the post id if the link refers to a post
  • the term id if the link refers to a taxonomy-term page
  • the post id of the custom link

So in what you want to do is check if the term actually refers to a post (or a custom post type), and then pass the object_id to the get_post_meta():

function wpse51076_special_nav_class($classes, $item){
    if( 'post' == $item->object ){
            $colorcode = get_post_meta($item->object_id, 'color_dropdown', true);
           $classes[] = $colorcode;
    return $classes;
add_filter('nav_menu_css_class' , 'wpse51076_special_nav_class' , 10 , 2);
share|improve this answer
Yay, works as it should now. I had to change post to page otherwise it works as intended. Thank you so much :) – INT May 5 '12 at 15:29
Yup, you can replace post with whichever post type you're after - or multiple post types :) – Stephen Harris May 5 '12 at 15:36

Try this, not tested.
I replaced $post->ID with $item->ID, should work.

add_filter('nav_menu_css_class' , 'special_nav_class' , 10 , 2);
function special_nav_class($classes, $item){
    global $post;
    $colorcode = get_post_meta($item->ID, 'color_dropdown', true);
    if(is_page()) {
        $classes[] = $colorcode;
    return $classes;
share|improve this answer

Your Answer


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.