Как стилизовать текущий пункт меню при использовании Walker в WordPress

18 дек. 2011 г., 21:47:25
Просмотры: 13.9K
Голосов: 2

Я создал пользовательское меню и хочу стилизовать отдельные элементы li в зависимости от того, является ли пункт текущей страницей или нет? Обычно это делается просто с помощью класса типа current-menu-item. Однако я также использую Walker в своей навигации для отображения дополнительного поля описания - это, похоже, отключает стандартные классы. Может кто-нибудь помочь?

<div id="navigation">

    <?php 
    $walker = new My_Walker; 
    wp_nav_menu(array( 'menu' => 'nav','walker' => $walker ) ); 
    ?>

</div><!-- END navigation -->

ОБНОВЛЕНИЕ:

class My_Walker extends Walker_Nav_Menu
{
    function start_el(&$output, $item, $depth, $args) {
        global $wp_query;
        $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';

        $class_names = $value = '';

        $classes = empty( $item->classes ) ? array() : (array) $item->classes;

        $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
        $class_names = '';

        $output .= $indent . '<li id="menu-item-'. $item->ID . '"' . $value . $class_names .'>';

        $attributes  = ! empty( $item->attr_title ) ? ' title="'  . esc_attr( $item->attr_title ) .'"' : '';
        $attributes .= ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
        $attributes .= ! empty( $item->xfn )        ? ' rel="'    . esc_attr( $item->xfn        ) .'"' : '';
        $attributes .= ! empty( $item->url )        ? ' href="'   . esc_attr( $item->url        ) .'"' : '';

        $item_output = $args->before;
        $item_output .= '<a'. $attributes .'>';
        $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
        $item_output .= '<span>' . $item->description . '</span>';
        $item_output .= '</a>';
        $item_output .= $args->after;

        $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
    }
}
2
Комментарии

CSS-класс 'current-menu-item' добавляется внутри вашего пользовательского класса-обходчика (walker class). Чтобы ответить на этот вопрос, нам нужно увидеть код, который вы используете для своего пользовательского обходчика.

patnz patnz
19 дек. 2011 г. 00:43:26

Спасибо patnz, я добавил дополнительный код выше, очень ценю это.

BrandyMedia BrandyMedia
19 дек. 2011 г. 22:54:12
Все ответы на вопрос 2
1

Поздний ответ, но решил внести свой вклад, так как эта страница была в топе Google при поиске решения данной проблемы. Я тоже упустил из виду тот факт, что WordPress по умолчанию добавляет текущий пункт меню (спасибо patnz за указание на это).

Однако мне не нравится, насколько раздута разметка при использовании стандартных классов, поэтому для тех, кому это интересно, можно использовать строку кода, подобную следующей:

$class_names = in_array("current_page_item",$item->classes) ? ' active' : '';

Для полноты картины — вот как это будет выглядеть в вашем примере кода:

class My_Walker extends Walker_Nav_Menu
{
    function start_el(&$output, $item, $depth, $args) {
        global $wp_query;
        $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';

        $class_names = $value = '';

        $classes = empty( $item->classes ) ? array() : (array) $item->classes;

        $class_names = in_array("current_page_item",$item->classes) ? ' active' : '';

        $output .= $indent . '<li id="menu-item-'. $item->ID . '"' . $value . $class_names .'>';

        $attributes  = ! empty( $item->attr_title ) ? ' title="'  . esc_attr( $item->attr_title ) .'"' : '';
        $attributes .= ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
        $attributes .= ! empty( $item->xfn )        ? ' rel="'    . esc_attr( $item->xfn        ) .'"' : '';
        $attributes .= ! empty( $item->url )        ? ' href="'   . esc_attr( $item->url        ) .'"' : '';

        $item_output = $args->before;
        $item_output .= '<a'. $attributes .'>';
        $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
        $item_output .= '<span>' . $item->description . '</span>';
        $item_output .= '</a>';
        $item_output .= $args->after;

        $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
    }
}
19 мар. 2012 г. 18:36:45
Комментарии

Очень позднее дополнение, но если вы используете архив пользовательского типа записи в качестве пункта меню, вам нужно изменить проверку in_array на "current-menu-item". Если сделать это, функция по-прежнему будет работать на отдельных страницах или записях. Не знаю, изменилось ли это с момента написания ответа 10 лет назад, поэтому мое решение, возможно, было недоступно в то время.

Rvervuurt Rvervuurt
2 июн. 2022 г. 09:28:12
1

Вы сбрасываете стандартные классы, поэтому они не добавляются.

// этот код очищает классы, которые должны быть добавлены
$class_names = '';

Попробуйте так:

class My_Walker extends Walker_Nav_Menu
{
    function start_el(&$output, $item, $depth, $args) {
        global $wp_query;
        $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';

        $class_names = $value = '';

        $classes = empty( $item->classes ) ? array() : (array) $item->classes;

        $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
        $class_names = ' class="' . esc_attr( $class_names ) . '"';

        $output .= $indent . '<li id="menu-item-'. $item->ID . '"' . $value . $class_names .'>';

        $attributes  = ! empty( $item->attr_title ) ? ' title="'  . esc_attr( $item->attr_title ) .'"' : '';
        $attributes .= ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
        $attributes .= ! empty( $item->xfn )        ? ' rel="'    . esc_attr( $item->xfn        ) .'"' : '';
        $attributes .= ! empty( $item->url )        ? ' href="'   . esc_attr( $item->url        ) .'"' : '';

        $item_output = $args->before;
        $item_output .= '<a'. $attributes .'>';
        $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
        $item_output .= '<span>' . $item->description . '</span>';
        $item_output .= '</a>';
        $item_output .= $args->after;

        $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
    }
}
20 дек. 2011 г. 00:02:32
Комментарии

Patnz, ты просто спаситель! Огромное спасибо! Обидно, что всего одна строка доставляла мне столько головной боли - ты герой, ура!

BrandyMedia BrandyMedia
20 дек. 2011 г. 22:50:42