Make WordPress Core

Opened 5 years ago

Closed 5 years ago

Last modified 5 years ago

#47533 closed defect (bug) (invalid)

wp_nav_menu() walker parameter breaks selective refresh

Reported by: sineway's profile sineway Owned by:
Milestone: Priority: normal
Severity: normal Version: 4.5
Component: Customize Keywords:
Focuses: Cc:

Description

Hello

I'm working on a theme where I need to use custom walker to archive desired HTML output for navigation menu.

Everything works like a charm, except selective refresh in customize preview is missing.

Seems it's not because of my walker, since you can specify default one to reproduce the issue:

wp_nav_menu([
    'walker' => new Walker_Nav_Menu
]);

In case there is a reason for such behavior, please point me to the right direction to get selective refresh running.

Thanks

Change History (7)

#1 @dlh
5 years ago

  • Component changed from Menus to Customize
  • Focuses ui administration removed
  • Milestone Awaiting Review deleted
  • Resolution set to invalid
  • Status changed from new to closed
  • Version changed from 5.2.1 to 4.5

Hi @sineway, and welcome to WordPress Trac!

The arguments passed to wp_nav_menu() need to be JSON-serializable for the menu to work with selective refresh.

The logic for determining whether a wp_nav_menu() can be selectively refreshed is documented in \WP_Customize_Nav_Menus::filter_wp_nav_menu_args(): https://github.com/WordPress/wordpress-develop/blob/8625ca01ec0c7a658ecd57b4ca246faa2a985491/src/wp-includes/class-wp-customize-nav-menus.php#L1356-L1384

For support for individual project, please try the support forums or WordPress Stack Exchange.

#2 @westonruter
5 years ago

The easy fix would be to pass a string instead of an instantiated class:

<?php
wp_nav_menu([
    'walker' => 'Walker_Nav_Menu'
]);

That should do it.

#3 @sineway
5 years ago

Thanks for your reply, guys!

I found out that there are conditions for why a menu change will get a full page refresh from this post by @westonruter

Then I made these steps:

(1) Instead of object, I passed just a walker's class name to wp_nav_menu() and initialize it later via filter wp_nav_menu_args.

The 'Click to edit' button appeared (it opens 'Locations' when I click it), but menu changes still trigger full page refresh.

(2) Then I added another filter - customize_dynamic_partial_args, where I override render_callback to display my partial, containing wp_nav_menu() call.

Now everything works, but I have concerns regarding step (2) cause I'm not sure whether it's right.

#5 @sineway
5 years ago

Without it menu behaves as if render_callback returns false.

For example, I change item order in left panel:

  1. Menu fades
  2. Entire page fades
  3. Full page refresh

Is it possible that $nav_menu_args was lost somewhere on the way?
I'm not sure, but seems they are not passed to render_callback?

Version 0, edited 5 years ago by sineway (next)

#7 @sineway
5 years ago

Looks like I found the reason.

The filter for the initialization of the walker in step 1 had priority 1000.
I changed it to 1001 and now it works without redundant step 2.

@westonruter @dlh
Thanks for helping me to figure it out!

Note: See TracTickets for help on using tickets.