WordPress обходчик добавляет класс к подменю a href

Вопрос или проблема

У меня возникли проблемы с моим кодом walker для WordPress. Я знаю, что возможно вручную добавить пользовательский CSS-класс через раздел административного меню. Но я пытаюсь добиться автоматического добавления этого класса каждый раз, когда мой клиент добавляет страницу подменю.

Первый шаг, который я предпринял, заключался в том, чтобы заменить навигацию ul li и изменить ее на стиль навигации a href. Это работает. Теперь я ищу способ добавить класс к элементам подменю a href

Вот как в данный момент выглядит мой walker.


class Description_Walker extends Walker_Nav_Menu {

    function start_el(&$output, $item, $depth, $args) {

        $classes = empty($item->classes) ? array () : (array) $item->classes;
        $class_names = join(' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
        !empty ( $class_names ) and $class_names=" class="". esc_attr( $class_names ) . '"';
        $output .= "";
        $attributes="";
        !empty( $item->attr_title ) and $attributes .= ' title="'  . esc_attr( $item->attr_title ) .'"';
        !empty( $item->target ) and $attributes .= ' target="' . esc_attr( $item->target     ) .'"';
        !empty( $item->xfn ) and $attributes .= ' rel="'    . esc_attr( $item->xfn        ) .'"';
        !empty( $item->url ) and $attributes .= ' href="'   . esc_attr( $item->url        ) .'"';
        $title = apply_filters( 'the_title', $item->title, $item->ID );
        $item_output = $args->before
        . "<a $attributes $class_names>"
        . $args->link_before
        . $title
        . '</a>'
        . $args->link_after
        . $args->after;

        if (array_search('menu-item-has-children', $item->classes)) {
            $output .= sprintf("\n<div data-delay='0' class="w-dropdown"><div class="dropdown-toggle"><div class="icon icon-dropdown-toggle"></div><div>$title</div></div>
                \n", ( array_search('current-menu-item', $item->classes) || array_search('current-page-parent', $item->classes) ) ? 'active' : '', $item->url,
                 $item->title);
         } else {
            $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
        }
    }

    function start_lvl(&$output, $depth, $args ) {
        $indent = str_repeat("\t", $depth);
        $output .= "\n$indent<nav class=\"dropdown-list\">\n<div class=\"submenu_speech\"></div>";
    }

    function end_lvl( &$output, $depth, $args = array() ) {
        $indent = str_repeat("\t", $depth);
        $output .= "$indent</nav></div>\n";
    }

    function end_el(&$output, $item, $depth, $args) {
        $output .= "\n";
    }

}

Существуют специальные фильтры для добавления классов к тегам ul, li или a в меню.

Для тегов a вы хотите использовать nav_menu_link_attributes. Это позволяет вам изменять все атрибуты на теге a, вот пример:

function my_nav_menu_link_attributes( $atts, $item, $args ) {
    if ( 'main' === $args->theme_location ) {
        if ( '0' === $item->menu_item_parent ) {
            $atts['class'] = 'top-level-item';
        } 
    }
    return $atts;
}
add_filter( 'nav_menu_link_attributes', 'my_nav_menu_link_attributes', 10, 3 );


class Description_Walker extends Walker_Nav_Menu
{
    function start_el(&$output, $item, $depth, $args)
    {
        $classes = empty($item->classes) ? array () : (array) $item->classes;

    if( $depth == 1 ){
      $class_names = join(' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
      !empty ( $class_names ) and $class_names=" class="dropdown-link w-dropdown-link ". esc_attr( $class_names ) . '"';
    } else {
      $class_names = join(' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
      !empty ( $class_names ) and $class_names=" class="". esc_attr( $class_names ) . '"';
    }

    $output .= "";
    $attributes="";
    !empty( $item->attr_title ) and $attributes .= ' title="'  . esc_attr( $item->attr_title ) .'"';
    !empty( $item->target ) and $attributes .= ' target="' . esc_attr( $item->target     ) .'"';
    !empty( $item->xfn ) and $attributes .= ' rel="'    . esc_attr( $item->xfn        ) .'"';
    !empty( $item->url ) and $attributes .= ' href="'   . esc_attr( $item->url        ) .'"';
    $title = apply_filters( 'the_title', $item->title, $item->ID );
    $item_output = $args->before
    . "<a $attributes $class_names>"
    . $args->link_before
    . $title
    . '</a>'
    . $args->link_after
    . $args->after;

            if (array_search('menu-item-has-children', $item->classes)) {
            $output .= sprintf("\n<div data-delay='0' class="w-dropdown"><div class="dropdown-toggle w-dropdown-toggle"><div class="icon w-icon-dropdown-toggle"></div><div>$title</div></div>
            \n", ( array_search('current-menu-item', $item->classes) || array_search('current-page-parent', $item->classes) ) ? 'active' : '', $item->url,
             $item->title);
        } else {

    $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
        }
}

    function start_lvl(&$output, $depth, $args ) {
            $indent = str_repeat("\t", $depth);
            $output .= "\n$indent<nav class=\"dropdown-list w-dropdown-list\">\n<div class=\"submenu_speech\"></div>";
    }

    function end_lvl( &$output, $depth, $args = array() ) {
            $indent = str_repeat("\t", $depth);
            $output .= "$indent</nav></div>\n";
    }

    function end_el(&$output, $item, $depth, $args) {
            $output .= "\n";
    }

}

Таким образом, когда $depth==1, к тегу a добавляется класс ‘dropdown-link w-dropdown-link’.

Это работает, но является ли это законным решением?

Ответ или решение

Ваш запрос касается изменения класса элементов подменю в WordPress с использованием кастомного класса "Walker". Вы сделали первый шаг, заменив традиционную структуру ul li на ссылки (a href), и теперь хотите добавить к подменю уникальный CSS класс. Это можно сделать при помощи вашего кастомного класса "Walker".

Шаги для реализации

  1. Определение уровня подменю:
    Ваша конструкция if ($depth == 1) правильно определяет, что мы находимся на уровне сразу под основным меню. Это необходимый условный оператор, который помогает назначить нужные классы именно для подменю.

  2. Добавление классов:
    Вы можете использовать массив классов, уже назначенных для меню, и расширять его, добавляя собственные стилевые классы:

    if ($depth == 1) {
       $class_names = join(' ', apply_filters('nav_menu_css_class', array_filter($classes), $item));
       !empty($class_names) and $class_names = ' class="dropdown-link w-dropdown-link ' . esc_attr($class_names) . '"';
    } else {
       $class_names = join(' ', apply_filters('nav_menu_css_class', array_filter($classes), $item));
       !empty($class_names) and $class_names = ' class="' . esc_attr($class_names) . '"';
    }
  3. Рендеринг элемента меню:
    Используя $item_output, вы создаете выходной элемент меню. Добавление атрибутов, таких как title, target, rel, и href, происходит корректно и соответствует лучшим практикам.

Использование фильтров

Существует фильтр nav_menu_link_attributes, который может быть полезен для добавления классов ко всем ссылкам меню. Это может упростить ваш код и сделать его более читаемым, особенно если у вас есть много элементов меню с разными атрибутами.

Пример использования:

function my_nav_menu_link_attributes($atts, $item, $args) {
    if ($item->menu_item_parent) {
        $atts['class'] = 'dropdown-link w-dropdown-link'; // Добавить класс для подменю
    }
    return $atts;
}
add_filter('nav_menu_link_attributes', 'my_nav_menu_link_attributes', 10, 3);

Заключение

Ваше текущее решение вполне законно, и оно делает именно то, что вы планировали. Исполняя ваши целевые требования, вы обеспечиваете, что классы для подменю добавляются автоматически. Использование как собственного класса Walker, так и фильтров WordPress дополнительно повышает гибкость и масштабируемость кода.

Для достижения оптимального результата рекомендуется также обращать внимание на кэширование ваших меню, чтобы предотвратить возможные проблемы с производительностью, особенно если места где эти меню используются, поддаются частому обновлению.

Если у вас возникнут дополнительные вопросы по данной теме, не стесняйтесь задать их.

Оцените материал
Добавить комментарий

Капча загружается...