WordPress.org

Make WordPress Core

Opened 11 years ago

Closed 10 years ago

Last modified 10 years ago

#14768 closed defect (bug) (wontfix)

Incorrect wp_nav_menu behavior when theme_location is set but no menus exist/assigned

Reported by: almostdaniel Owned by: jnthnlstr
Milestone: Priority: normal
Severity: normal Version: 3.0.1
Component: Menus Keywords: close needs-codex
Focuses: Cc:

Description

The Codex Function Reference for wp_nav_menu states:

Given a theme_location parameter, the function displays the menu assigned to that location, or nothing if no such location exists or no menu is assigned to it.

In my theme functions.php, I have registered two nav menu locations:

	register_nav_menus( array(
		'primary' => __( 'Primary Navigation' ),
		'secondary' => __( 'Secondary Navigation' ),
	) );

In my theme header.php, I call for the location menus:

wp_nav_menu( array( 'container' => 'div', 'container_id' => 'index-nav', 'theme_location' => 'secondary' ) );
wp_nav_menu( array( 'container' => 'div', 'container_id' => 'toc-nav', 'theme_location' => 'primary' ) );

I do not have any menus created or assigned to those locations. However, based on the Codex, I expect that nothing will be displayed.

However, the wp_nav_menu functions are falling back to the callback function, wp_page_menu. That decision is made in this part of the wp_nav_menu function:

	// If no menu was found or if the menu has no items and no location was requested, call the fallback_cb if it exists
	if ( ( !$menu || is_wp_error($menu) || ( isset($menu_items) && empty($menu_items) && !$args->theme_location ) )
		&& ( function_exists($args->fallback_cb) || is_callable( $args->fallback_cb ) ) ) {

This logic overrides the statement in the Codex. If by this point no menu has been found (and it won't be, because each of the checks before get overrided by there being a $args->theme_location set), I automatically use the callback function–no matter if I have specified a theme_location or not. This is due to the first OR parameter "!$menu || ...". The only way my theme_location specification prevents this is if a menu was found. But that's impossible because theme_location prevents it from being found.

I think the pattern from the previous checks should be carried on to this final check. Not sure if this would break some other logic, but it would at least match the Codex description.

	// If no menu was found or if the menu has no items, and no location was requested, call the fallback_cb if it exists
	if ( ( !$menu || is_wp_error($menu) || ( isset($menu_items) && empty($menu_items)  ) )
		&& ( function_exists($args->fallback_cb) || is_callable( $args->fallback_cb ) ) 
		&& !$args->theme_location) {

Attachments (1)

nav-menu-template.patch.php (172 bytes) - added by jnthnlstr 11 years ago.

Download all attachments as: .zip

Change History (11)

#1 @jnthnlstr
11 years ago

  • Owner set to jnthnlstr
  • Status changed from new to reviewing

#2 @jnthnlstr
11 years ago

I agree.

I think this function should just exit if it finds that the theme_location parameter is pointing to a value that doesn't exist.

#3 @jnthnlstr
11 years ago

  • Keywords has-patch added
  • Resolution set to fixed
  • Status changed from reviewing to closed

#4 @jnthnlstr
11 years ago

  • Resolution fixed deleted
  • Status changed from closed to reopened

#5 @jnthnlstr
11 years ago

  • Status changed from reopened to accepted

#6 @filosofo
11 years ago

There's a simple way to produce the behavior you want: just call wp_nav_menu with the fallback_cb argument set to null.

For backwards-compatibility reasons, I don't think you will get support to change the default behavior.

#7 @filosofo
11 years ago

  • Keywords close added; wp_nav_menu theme_location has-patch removed
  • Milestone changed from Awaiting Review to 3.1

I forgot to mention that the Codex, like any wiki, is user-generated. So that means both that it's not always authoritative and that you can correct it yourself.

#8 @jnthnlstr
11 years ago

Thanks filosofo, and I appreciate the comment about backwards-compatibility.

#9 @nacin
10 years ago

  • Milestone 3.1 deleted
  • Resolution set to wontfix
  • Status changed from accepted to closed

#10 @nacin
10 years ago

  • Keywords needs-codex added
Note: See TracTickets for help on using tickets.