Opened 14 years ago
Last modified 5 years ago
#14142 reopened defect (bug)
Custom Walker class for navigation menus
Reported by: | dennis.winter | Owned by: | |
---|---|---|---|
Milestone: | Future Release | Priority: | normal |
Severity: | normal | Version: | 3.0 |
Component: | Menus | Keywords: | needs-patch |
Focuses: | Cc: |
Description
I have tried to extend the Walker_Nav_Menu class, I just needed to overwrite the start_el method. So i added "walker"=>"My_Walker" to wp_nav_menu, I've got an error message, that the method "walk" could not be accessed statically. After a short look at the code in "nav-menu-template", I realized that in the method "walk_nav_menu_tree" the object initializer "new" is missing.
My solution can be found in the attached file.
As you can see, I've just added a "new" in front of $r->walker
And it works
Attachments (1)
Change History (14)
#2
follow-up:
↓ 3
@
14 years ago
Ok, then the documentation has to be changed! "(string) (optional) Custom walker to use" this implies a String has to be used!
#3
in reply to:
↑ 2
@
14 years ago
Replying to dennis.winter:
Ok, then the documentation has to be changed! "(string) (optional) Custom walker to use" this implies a String has to be used!
Where does it say this?
#5
@
14 years ago
- Keywords has-patch removed
- Milestone Awaiting Review deleted
- Resolution set to invalid
- Severity changed from major to normal
- Status changed from new to closed
The Codex is a wiki, so any logged-in user can edit it. I just changed it to say "object."
This ticket was mentioned in Slack in #core by nyordanov. View the logs.
8 years ago
#8
@
8 years ago
- Keywords needs-patch added
- Milestone set to Future Release
- Resolution invalid deleted
- Status changed from closed to reopened
Nav menus in the customizer can be previewed with selective refresh when the walker
is JSON-serializable per https://make.wordpress.org/core/2015/07/29/fast-previewing-changes-to-menus-in-the-customizer/
The logic in \WP_Customize_Nav_Menus::filter_wp_nav_menu_args()
allows selective refresh if walker
is empty or a class string. If wp_nav_menu()
is called with an instantiated walker object, this cannot be JSON-serialized, and so it cannot be selectively refreshed. Therefore, a string should be able to be passed in in addition to passing in a pre-instantiated object.
The patch in nav-menu-template.diff isn't quite right. It should do this instead:
- $walker = ( empty($r->walker) ) ? new Walker_Nav_Menu : $r->walker; + $walker = $r->walker; + if ( ! empty( $r->walker ) && is_string( $r->walker ) ) { + $walker = new $walker; + }
The phpdoc @param
also need to be updated.
#9
@
7 years ago
This has re-surfaced in https://wordpress.stackexchange.com/q/295461/8521
#12
@
6 years ago
- Milestone changed from 5.1 to Future Release
This ticket needs testing and a decision.
#13
@
5 years ago
Custom walker won't be to utilize "Partial Refresh", if walker object is passed.
So after reading reviewing
https://github.com/WordPress/WordPress/blob/4f35907147df1afdc99143af3813604967807a40/wp-includes/class-wp-customize-nav-menus.php#L1369
I passed "Walker Class name as string" and it didn't worked either, was throwing
`
PHP Fatal error: Using $this when not in object context
`
Then I saw this post
https://wordpress.stackexchange.com/q/295461/8521
And in combination with passing walker as string and applying this filter solves my issue.
So patching this function
https://github.com/WordPress/WordPress/blob/7d74080b80bf0fee57de5f9c7137c9b4e31e3953/wp-includes/nav-menu-template.php#L576
as
function walk_nav_menu_tree( $items, $depth, $r ) { $walker = $r->walker; if ( ! empty( $r->walker ) && is_string( $r->walker ) ) { $walker = new $walker; } else { $walker = new Walker_Nav_Menu; } $args = array( $items, $depth, $r ); return call_user_func_array( array( $walker, 'walk' ), $args ); }
solves the issue.
"walker" should be an instantiated object, not a class name.