1

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?

EDIT: UPDATED MY QUESTION

3
  • Your example works, are you sure the meta key is in the page and the nav menu is setup?
    – ampt
    May 4, 2012 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, 2012 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, 2012 at 10:03

2 Answers 2

2

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);
2
  • 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, 2012 at 15:29
  • Yup, you can replace post with whichever post type you're after - or multiple post types :) May 5, 2012 at 15:36
0

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;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.