0

I have a website that uses a plugin that lets me add categories and tags to pages.

Is there a way of automatically changing the color of a menu item linked to all pages with a particular tag or category?

Specifically, I want to add the class "unwatched" to the menu item of any page that has been tagged with the "unwatched" tag.

I have tried the following code but I'm sure I've got it wrong: (it didn't work)

add_filter('nav_menu_css_class', 'custom_nav_menu_css_class', 10, 2 );

function custom_nav_menu_css_class( $classes, $item ) {
    if( 'tag' === $item->object ){
        array_push( $classes, 'unwatched' ); 
    }
    return $classes;    
}
  • It is probably a duplicate question. Here is the answer wordpress.stackexchange.com/a/109270/9821 – pixelngrain Dec 24 '19 at 2:44
  • I don't want to have to manually add a class to individual menu items though; I'd like it to be done dynamically, depending on what categories or tags the page has – cobberas63 Dec 24 '19 at 2:50
  • You may still use the code I referred to. Change the conditional statement to check with your taxonomy conditionally and add the CSS class to your menu item. Then use that class in CSS. If this is not enough then share what you have done till now. Without reference, no one would be able to help you. – pixelngrain Dec 24 '19 at 2:59
  • Yes, I want to "Change the conditional statement to check with your taxonomy conditionally and add the CSS class to your menu item" - I want to add the class "unwatched" to the menu item of any page that has been tagged with the "unwatched" tagged. – cobberas63 Dec 24 '19 at 4:16
1

OK, got it :-)

add_filter( 'wp_nav_menu_objects', 'add_nav_menu_item_class' );

function add_nav_menu_item_class( $items ) {
    foreach ( $items as $item ) {
        $post_id = get_post_meta( $item->ID, '_menu_item_object_id', true );
        $post_tags = get_the_tags( $post_id );
        if ( $post_tags ) {
            foreach( $post_tags as $tag ) {
                if  ( $tag->name == 'unwatched' ) {
                    $item->classes[] = 'unwatched';
                }
            }
        }
    }
    return $items;
}

The associated CSS, which changes the color of all menu items tagged with the 'unwatched' class, is

li.unwatched > a {
    color: FORESTGREEN;
}
|improve this answer|||||
0

My next effort:

add_filter( 'wp_nav_menu_objects', 'add_nav_menu_item_class' );

function add_nav_menu_item_class( $items ) {
    foreach ( $items as $item ) {
        $post_tags = get_the_tags();
        if ( $post_tags ) {
            foreach( $post_tags as $tag ) {
                if  ( $tag->name == 'unwatched' ) {
                    $item->classes[] = 'unwatched';
                }
            }
        }
    }
    return $items;
}

This has an interesting effect - if the page I'm looking at has the 'unwatched' tag, ALL my menu items have the 'unwatched' class; conversely, if the page I'm looking at doesn't have the 'unwatched' tag, NONE of my menu items have the 'unwatched' class.

Maybe it's not possible to achieve this, but what I want is for the 'unwatched' class to be on every menu item linked to a page that has the 'unwatched' tag, and none of the others, regardless of which page I'm currently looking at.

|improve this answer|||||
0

Instead of using array_push() try using $item->classes[] = 'unwatched';

Although the more I look at it, where is your code checking if the tag is 'unwatched'?

You're pushing 'unwatched' into the classes array but your tag check isn't referencing it?

Is there more code that's not displayed here?

UPDATE Looking at your second effort I think I understand where the issue is... ...when a page is loaded you're checking to see if the tag is present for the page that is loaded by using 'get_the_tags()', you're not checking if all of the pages associated with the menu items have that tag. Since the result returns TRUE for that page, then the foreach adds the class to each.

What you need to do is, in the foreach, check the tags for each specific page/post ID and then add the class dependent on that. So within the foreach you'd need get_the_tags( $item->ID ). May need more work than just that to ensure you're getting the ID of each item, but I think that's the right way to go about doing applying the class.

|improve this answer|||||
  • That's all I have for now, but I'll have another go. – cobberas63 Dec 27 '19 at 7:11
  • Re UPDATE: Something not right here. $post_tags = get_the_tags( $item->ID ); doesn't return anything. $post_tags = get_the_tags( ); returns all the tags of the post currently being displayed. I need the tags of each menu item's associated post but I can't figure out how to do that :-( – cobberas63 Jan 7 at 5:24
  • I'm wondering if I need o create a Custom Walker for wp_nav_menu() e.g. wordpress.stackexchange.com/questions/14037/… – cobberas63 Jan 7 at 6:27
  • I don't think so... ...if get_tags( $item->ID ) isn't returning anything then it may not be properly pulling the ID. Can you set the IDs into a variable first and ensure that it is getting IDs. To test you could try just hardcoding an ID that you know has the tag and var_dump the results to confirm. – Tony Djukic Jan 7 at 15:18
  • You're right, @Tony Djukic, the line I need is $post_id = get_post_meta( $item->ID, '_menu_item_object_id', true ); (from wordpress.stackexchange.com/questions/13604/…) Thanks :-) – cobberas63 Jan 9 at 22:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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