Add featured image to wp_nav_menu items Add featured image to wp_nav_menu items wordpress wordpress

Add featured image to wp_nav_menu items


This is the code I came up with thanks to some help from a Wordpress StackOverflow answer that I can't find anymore (please comment with a link if you find it).

First you need to add the filter to the specific menu (you could add it to all menus if you want - just use the add_filter line by itself).

// Add filter to specific menus add_filter('wp_nav_menu_args', 'add_filter_to_menus');function add_filter_to_menus($args) {    // You can test agasint things like $args['menu'], $args['menu_id'] or $args['theme_location']    if( $args['theme_location'] == 'header_menu') {        add_filter( 'wp_setup_nav_menu_item', 'filter_menu_items' );    }    return $args;}

Then you need to build out the code to get the post or category ID from the $item object passed to the filter. It's not as easy as you'd expect, as $item doesn't contain the underlying post/category ID, just the menu item ID. So I use the URL's to do a reverse lookup of the IDs.

This won't work for tags used in a menu, or custom taxonomys. I only needed it for categories, so this is all I built.

// Filter menufunction filter_menu_items($item) {    if( $item->type == 'taxonomy') {        // For category menu items        $cat_base = get_option('category_base');        if( empty($cat_base) ) {            $cat_base = 'category';        }        // Get the path to the category (excluding the home and category base parts of the URL)        $cat_path = str_replace(home_url().'/'.$cat_base, '', $item->url);        // Get category and image ID        $cat = get_category_by_path($cat_path, true);        $thumb_id = get_term_meta($cat->term_id, '_term_image_id', true); // I'm using the 'Simple Term Meta' plugin to store an attachment ID as the featured image    } else {        // Get post and image ID        $post_id = url_to_postid( $item->url );        $thumb_id = get_post_thumbnail_id( $post_id );    }    if( !empty($thumb_id) ) {        // Make the title just be the featured image.        $item->title = wp_get_attachment_image( $thumb_id, 'poster');    }    return $item;}

And then you want to remove the filter that you applied at the beginning, so that the next menu processed doesn't use the same HTML as defined above in filter_menu_items().

// Remove filtersadd_filter('wp_nav_menu_items','remove_filter_from_menus', 10, 2);function remove_filter_from_menus( $nav, $args ) {    remove_filter( 'wp_setup_nav_menu_item', 'filter_menu_items' );    return $nav;}