Wordpress: Menu Descriptions using HTML

To use the WordPress built-in menu feature is simply awesome because it supports many features. One of them is that you can use descriptions along individual menu items. However, this feature is hidden by default and you need to enable it by using the options anchor in the top right. That is only half of it, you also need to add some code to your theme to overwrite the old menu walker and integrate your own one using the menu descriptions. Though that is not the subject of this post.

Once you got the descriptions working you may notice a setback. You cannot use html code within your descriptions. If you use HTML it will enable you to insert images in front of the menu title or something else. To get that working there is a little trick. This code, if added to your themes, enables the descriptions for html tags.

remove_filter('nav_menu_description', 'strip_tags');

Anyway, that is not working anymore, at least not alone. So you have to extend it. The HTML stripping code is now hardcoded and cannot be removed. To get it working again we need to bend the WordPress system a bit more. Menu items have some properties, containing:

menu_item->post_content - description with html tags
menu_item-> description - description with stripped html tags

So we can use menu_item->post_content for a proper display of the description. But there is still the problem within the backend. We can store the html code, but after saving the whole menu we cannot see it anymore (but post_content still hold the right version). We can use this to get our description working well if we utilise the code below.

remove_filter('nav_menu_description', 'strip_tags');
add_filter( 'wp_setup_nav_menu_item', 'cus_wp_setup_nav_menu_item' );
function cus_wp_setup_nav_menu_item($menu_item) {
$menu_item->description = apply_filters('nav_menu_description', $menu_item->post_content );
return $menu_item;

There is still a problem. The Addition of a new menu item to our menu will bring the related page or post content into our description field. However, we can avoid this by using a little statement to compare the type of the menu item with the type of the loaded content. If they match we can use the content.

remove_filter( 'nav_menu_description', 'strip_tags' );
add_filter( 'wp_setup_nav_menu_item', 'dis14_wp_setup_nav_menu_item' );
function dis14_wp_setup_nav_menu_item( $menuItem ) {
if ( isset( $menuItem->post_type ) && 'nav_menu_item' == $menuItem->post_type ) {
$menuItem->description = apply_filters( 'nav_menu_description', $menuItem->post_content );
return $menuItem;

That is it!