2

Spent two days researching this. I need to be able to add HTML to the Custom Menus Description. Everything I can find (including on this site) is from Feb 2011 and mentions using a strip_tags filter. However, that no longer works. I'm developing on WP 3.4 Beta 4.

I've created a custom walker class and found a filter to remove HTML tags and put the following into functions.php:

// Custom Walker Class to extend Default Nav Menu
class Description_Walker extends Walker_Nav_Menu {

function start_el(&$output, $item, $depth, $args)
{
    $classes     = empty ( $item->classes ) ? array () : (array) $item->classes;

    $class_names = join(
        ' '
    ,   apply_filters(
            'nav_menu_css_class'
        ,   array_filter( $classes ), $item
        )
    );

    ! empty ( $class_names )
        and $class_names = ' class="'. esc_attr( $class_names ) . '"';

// Build default menu items
    $output .= "<li id='menu-item-$item->ID' $class_names>";

    $attributes  = '';

    ! empty( $item->attr_title )
        and $attributes .= ' title="'  . esc_attr( $item->attr_title ) .'"';
    ! empty( $item->target )
        and $attributes .= ' target="' . esc_attr( $item->target     ) .'"';
    ! empty( $item->xfn )
        and $attributes .= ' rel="'    . esc_attr( $item->xfn        ) .'"';
    ! empty( $item->url )
        and $attributes .= ' href="'   . esc_attr( $item->url        ) .'"';

// Build the description
    $description = ( ! empty ( $item->description ) and 1 == $depth )
        ? '<span class="nav_desc">' . esc_html( $item->description ) . '</span>' : '';

    $title = apply_filters( 'the_title', $item->title, $item->ID );

    $item_output = $args->before
        . "<a $attributes>"
        . $args->link_before
        . $title
        . '</a> '
        . $args->link_after
        . $description
        . $args->after;

    // Since $output is called by reference we don't need to return anything.
    $output .= apply_filters(
        'walker_nav_menu_start_el'
    ,   $item_output
    ,   $item
    ,   $depth
    ,   $args
    );
}
}

// Allow HTML descriptions in WordPress Menu
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;
}

Then used the following to spit out the menu:

<?php wp_nav_menu( array( 'theme_location' => 'primary', 'menu' => 'primary', 'menu_class' => 'menu sf-menu', 'walker' => new Description_Walker )); ?>

However, the html tags are still be stripped! See the Screen Shots:

Menu Description

Results

2

(Untested). But if you want to use HTML in the description, then you shouldn't use:

`esc_html( $item->description )`

Try removing the esc_html as this escapes the HTML. (Or better still use wp_kses instead to only allow certain tags.).

So you want

$description = ( ! empty ( $item->post_content ) and 1 == $depth )
    ? '<span class="nav_desc">' .$item->post_content . '</span>' : '';

And you still want the remove_filter( 'nav_menu_description', 'strip_tags' );, but the cus_wp_setup_nav_menu_item function is unnecessary.

Although I don't in the above example, I would recommend using wp_kses.

  • Changed it to esc_attr. Still getting this result: <span class="nav_desc"> &lt;strong&gt;Snowboarder&lt;/strong&gt; &lt;img src=&quot;http://fmg.gregrickaby.com/wp-content/uploads/2012/05/nav-aimee-fuller.jpg&quot;&gt;</span></li> – Greg May 9 '12 at 13:43
  • @Greg No, remove any escaping. – fuxia May 9 '12 at 13:47
  • @Greg esc_attr is really the same as esc_html. If you want to use HTML in the description, you don't want to escape any HTML - (or escape some with wp_kses). See update answer. – Stephen Harris May 9 '12 at 14:02
  • 1
    That worked! Thank you! However, I needed to keep the cus_wp_setup_nav_menu_item function. Remove it stripped the HTML. Here is the full working code: pastebin.com/XmjtUyAg – Greg May 9 '12 at 14:14
  • This is correct, we have to manually re-attach post_content to $menu_item->description attribute, because add_filter nav_menu_description only passes text value as an argument core.trac.wordpress.org/browser/tags/5.3/src/wp-includes/… – lkraav yesterday

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.