фильтр wp-настраиваемого меню удаляет текущий класс элементов страницы


После добавления плагина wp-custom-menu-filter - чтобы скрыть некоторые пункты меню для пользователей, не вошедших в систему, класс current_page_item исчез из моего меню. $item->classes в ходунке есть пустой массив, вместо обычного page-item-$id, current_page_item.

Я посмотрел на источник, но он не изменяет массив классов, поэтому я не знаю, что происходит. Вот соответствующая часть кодекса.

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);

Я использую пользовательский ходок по страницам, я пробовал использовать тот, что по умолчанию, с никакого эффекта, и пользовательский работает просто отлично без этого плагина. Вот код ходока:

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 );
  }
}

Я согласен с тем, чтобы использовать другой способ скрыть пункты меню для пользователей, не вошедших в систему, вместо исправления плагина, но, поскольку я никогда не использовал wp_nav_menu_objects, я действительно не знаю, что происходит.

Author: Maxim Krizhanovsky, 2011-10-21

1 answers

После нескольких часов отладки я обнаружил, что wps_custom_nav_menu_items() фактически получает nav_menu_items с классами, применяемыми _wp_menu_item_classes_by_context, но вместо того, чтобы использовать их, он перезагружает все меню из базы данных! Поэтому, если вы измените

$nav_items = wp_get_nav_menu_items( $menu_id );

До

$nav_items = $args;

(или просто удалите строку и переименуйте аргумент функции), он работает так, как ожидалось.

 0
Author: Maxim Krizhanovsky, 2011-10-21 12:06:59