Adding shortcode to the main menu

I thought about making this a plugin since so many people ask about it, but here’s what you can do. This is by far the most consistent option that I’ve found because it allows you to do virtually anything you want in menus and doesn’t require writing your own walker class.

Install stag custom sidebars

Add this to your functions.php or personal plugin.

if( !function_exists('shortcode_my_menu') ) {
    function shortcode_my_menu( $item_output, $item ) {
        if ( !empty($item->description)) {
             $output = do_shortcode($item->description);
             if ( $output != $item->description )
                  $item_output = $output;  
            }
        return $item_output;    
    }
    add_filter("walker_nav_menu_start_el", "shortcode_my_menu" , 10 , 2);
}

if( !function_exists('eval_to_allow_php_in_text_widget') ) {
function eval_to_allow_php_in_text_widget($text) {
    ob_start();
    eval('?>'
    .$text);
    $text = ob_get_contents();
    ob_end_clean();
    return $text;
}
add_filter('widget_text', 'do_shortcode');
add_filter( 'widget_title', 'do_shortcode' );
add_filter('widget_text', 'eval_to_allow_php_in_text_widget');
add_filter('widget_title', 'eval_to_allow_php_in_text_widget');
}

If you give access to widgets to other users I’d suggest doing something like this with the above:

if (current_user_can('administrator'))

This way you are the only one who has permission to execute php in the widget text.

Basically using stag custom sidebars create a sidebar quickly. It will generate a shortcode that lets you add it anywhere in your site. With the first function above you can safely add shortcodes in your menu descriptions. When you add the shortcode that stag creates in the menu description it will add whatever widgets you added to that sidebar and replace that specific menu item. The second function lets you add shortcodes in widgets and also use php.

Using this method it completely eliminates the need ever create custom menu walkers because you can do it all from within widgets.

Additionally you can use these which adds the ability to add html directly to the description… However, you would need to have descriptions available in your themes menu template for it to work:

remove_filter('nav_menu_description', 'wptexturize');
remove_filter('nav_menu_description', 'strip_tags');

add_filter( 'wp_setup_nav_menu_item', 'html_nav_menu_description' );
function html_nav_menu_description($menu_item) {
    $menu_item->description = apply_filters( 'nav_menu_description',  $menu_item->post_content );
    return $menu_item;
} 

And even some more shortcodes in menus that I haven’t tested:

add_filter('wp_nav_menu', 'do_shortcode', 11);
add_filter('wp_nav_menu_items', 'do_shortcode');

If you have any issues with formatting like p and break tags around shortcodes try andding this function to the filters:

function fix_shortcode_output($content){   
    $array = array (
        '[' => '[', 
        ']' => ']', 
        ']' => ']'
    );
    $patternp = '/]*>\[/'; 
    $content = strtr($content, $array);
    $content = preg_replace($patternp, "[", $content);
    return $content;
}