After adding wp-custom-menu-filter plugin – to hide some menu items for not-logged in users, the current_page_item class disappeared from my menu. $item->classes
in the walker is an empty array, instead of usual page-item-$id
, current_page_item
.
I’ve looked at the source, but it does not modify the classes array, so I don’t know what’s going on. Here is the relevant part of the code.
function wps_custom_nav_menu_items( $args ){
global $wpcmfp_settings;
$nav_item_db_id = $args[1]->ID;
$nav_menu = wp_get_object_terms( $nav_item_db_id, 'nav_menu' );
$menu_id = $nav_menu[0]->term_id;
// Get the class to exclude
if ( !is_user_logged_in() ) {
$exclusion_class = $wpcmfp_settings[ 'menu-' . $menu_id . '-loggedout' ];
}
else {
$exclusion_class = $wpcmfp_settings[ 'menu-' . $menu_id . '-loggedin' ];
}
$nav_items = wp_get_nav_menu_items( $menu_id );
// Cycle through all nav_items
foreach ( $nav_items as $nav_item ) {
// Cycle through all classes
for ( $i=0; $i < count( $nav_item->classes ); $i++ ) {
$exclude = false;
// if nothing is there set to add
if ( strlen ( $nav_item->classes[ $i ] ) < 1 ) {
$exclude = false;
}
else
{
// if matches add to exclusion array & break loop
if ( $nav_item->classes[ $i ] == $exclusion_class ) {
$excluded_nav_items[] = $nav_item;
$exclude = true;
break;
}
}
}
if ( $exclude != true )
$modified_nav_items[] = $nav_item;
}
return $modified_nav_items;
}
add_filter( 'wp_nav_menu_objects', 'wps_custom_nav_menu_items' , 10 , 3);
I’m using custom page walker, I’ve tried using the default one with no effect, and the custom one works just fine without this plugin. Here is the code of the walker:
class My_Walker_Page extends Walker_Nav_Menu {
protected $_counter = 0;
protected $_itemsPerColumn = 1;
function start_lvl(&$output, $depth) {
$this->_counter = 0;
$output .= '<some html>';
}
function end_lvl(&$output, $depth) {
$output .= '<some html>';
$this->_counter = 0;
}
function start_el(&$output, $page, $depth, $args, $current_page = null) {
$args = ( array ) $args;
if ($depth == 0) {
return parent::start_el ( $output, $page, $depth, $args, $current_page );
}
if ($depth == 1) {
extract ( $args, EXTR_SKIP );
$output .= '<dt><a href="' . esc_attr ( $page->url ) . '" title="' . esc_attr ( wp_strip_all_tags ( apply_filters ( 'the_title', $page->title, $page->ID ) ) ) . '">' . $link_before . apply_filters ( 'the_title', $page->title, $page->ID ) . $link_after . '</a>';
if (! empty ( $page->description )) {
$output .= '<span class="menu_item_description">' . $page->description . '</span>';
}
$output .= '</dt>';
$this->_counter ++;
if ($this->_counter % $this->_itemsPerColumn == 0) {
$output .= '</dl><dl>';
}
}
}
function end_el(&$output, $page, $depth) {
if ($depth == 0) {
return parent::end_el ( &$output, $page, $depth );
}
}
function display_element($element, &$children_elements, $max_depth, $depth = 0, $args, &$output) {
if (! $element)
return;
$id_field = $this->db_fields ['id'];
if ($depth == 0) {
$this->_itemsPerColumn = ceil ( count ( $children_elements [$element->$id_field] ) / 4 );
}
return parent::display_element ( $element, $children_elements, $max_depth, $depth, $args, $output );
}
}
I’m OK with going with another way to hide menu items for non-logged in users, instead of fixing the plugin, but since I’ve never used the wp_nav_menu_objects
I really don’t know what is going on.
After few hours of debugging I found out, that the wps_custom_nav_menu_items() actually receives the nav_menu_items with classes, applied by the _wp_menu_item_classes_by_context, but instead of using them, it reloads the entire menu from the database!
So if you change
To
(or just remove the line and rename the function argument), it works as expected.