Make WordPress Core

Opened 3 years ago

Closed 3 years ago

Last modified 3 years ago

#21302 closed defect (bug) (invalid)

possible bug with wp_nav_menu(), not allowing code to be wrapped around the output

Reported by: anointed Owned by:
Milestone: Priority: normal
Severity: normal Version: 3.0
Component: Menus Keywords:
Focuses: Cc:


I had a need to insert a div with a text link just prior to the wp_nav_menu() 'ul' output. So, following a tutorial I added a simple function that would 'wrap' the nav menu with beginning and ending variables. The problem I ran into is that no matter what I tried, the div with the text link 'Menu' would always show up after the menu 'ul' and not before.

Code snippet:

function tumble_menu( $args = array() ) {
	/* Default arguments */
	$defaults = array(
		'container' 		=> 'ul',
		'menu_class' 		=> 'nav',
		'menu_id'		=> 'top_nav',
		'theme_location' 	=> 'top-menu',
		'echo' 			=> true,
		'before' 		=> '',
		'after' 		=> '',
		'link_before' 		=> '',
		'link_after' 		=> '',
		'depth' 		=> 1,
		'sort_column'		=> 'menu_order',
                'show_container'        => false,
		'walker'		=> ''
	$defaults 	= apply_filters( 'tumble_nav_default_args', $defaults);
	$args 		= wp_parse_args( $args, $defaults );

	$main_menu = wp_nav_menu( $args );
function tumble_add_menu_wrapper($html, $begin, $end) {
	// wrap our original HTML with the new tags
	$html = $begin . $html . $end;
	return $html;
add_filter( 'tumble_menu_wrap', 'tumble_add_menu_wrapper', 10, 3 );

function tumble_do_menu_wrapper() {
	$html = tumble_menu();
	echo apply_filters( 'tumble_menu_wrap', $html, 'div class="menu-button">Menu/div','' );

*I had to modify the echo in the last function to remove the brackets on the div due to the editor stripping it out here.

After spending most of the afternoon on this problem with Pippin, we determined that it is probably a bug with the core wp_nav_menu() function.

Just in case it helps, here is the same function that does work as expected, only not using wp_nav_menu().


function pippin_sample_html() {	
	ob_start(); ?>	
		<li>List Item <em>One</em></li>
		<li>List <strong>Item</strong> Two</li>
		<li>List Item <a href="#">Three</a></li>
	return ob_get_clean();

function pippin_add_html_wrapper($html, $begin, $end) {
	// wrap our original HTML with the new tags
	$html = $begin . $html . $end;
	return $html;
add_filter('pippin_html_wrap', 'pippin_add_html_wrapper', 10, 3);

function pippin_print_html() {
	$html = pippin_sample_html();
	echo apply_filters('pippin_html_wrap', $html, 'div id="sample_wrapper">hello world/div', '');

This function, 'almost identical to the first one', does indeed place the 'hello world' prior to the opening 'ul'.

Change History (5)

#1 @SergeyBiryukov
3 years ago

As far as I can see, you just need 'echo' => false in tumble_menu().

#2 @anointed
3 years ago

Just tried that again to make sure, and no, doesn't solve the problem.

Last edited 3 years ago by anointed (previous) (diff)

#3 @SergeyBiryukov
3 years ago

Tried your example. tumble_menu() needs two fixes:

  1. Replace 'echo' => true with 'echo' => false.
  2. Add return $main_menu; to the end of the function (otherwise $html = tumble_menu() is null).

Once I changed that, the wrapper was displayed correctly.

#4 @anointed
3 years ago

  • Resolution set to invalid
  • Status changed from new to closed

Thanks Sergey
I'm sorry for the erroneous ticket. We really did try hard before even considering a trac ticket. I suppose next time I need to ask around more before submitting a ticket.

#5 @SergeyBiryukov
3 years ago

  • Milestone Awaiting Review deleted

No problem :)

Note: See TracTickets for help on using tickets.