WordPress.org

Make WordPress Core

Opened 4 years ago

Closed 3 years ago

Last modified 3 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 4 years ago.

Download all attachments as: .zip

Change History (11)

comment:1 jnthnlstr4 years ago

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

comment:2 jnthnlstr4 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.

comment:3 jnthnlstr4 years ago

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

comment:4 jnthnlstr4 years ago

  • Resolution fixed deleted
  • Status changed from closed to reopened

comment:5 jnthnlstr4 years ago

  • Status changed from reopened to accepted

comment:6 filosofo4 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.

comment:7 filosofo4 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.

comment:8 jnthnlstr4 years ago

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

comment:9 nacin3 years ago

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

comment:10 nacin3 years ago

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