Подсветите пункт меню с страницами записей.

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

У меня проблема с основной навигацией на WP, которую я разрабатываю локально с Wamp. Искал решение в течение нескольких часов, но безуспешно. Вот мой код:

HTML (php)

<div id="primary-nav" class="primary-nav-container" role="navigation">
    <ul id="primary-menu" class="sf-menu primary-menu">
        <li id="menu-item-8" class="menu-item menu-item-type-post_type menu-item-object-page current-menu-item page_item page-item-5 current_page_item menu-item-8"><a href="http://localhost/sw/">ГЛАВНАЯ</a></li>
        <li id="menu-item-241" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-241"><a href="http://localhost/sw/articles/">Статьи</a></li>
        <li id="menu-item-339" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-339"><a href="http://localhost/sw/blog/">Блог</a></li>
        <li id="menu-item-437" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-437"><a href="http://localhost/sw/forum/">Форум</a></li>
    </ul>   
</div>

CSS выделение

.primary-menu > li > a:hover,
.primary-menu > .current-menu-item > a,
.primary-menu > .sfHover > a {
    border-bottom: 5px solid #ddff34;
    color: #fff;
}

Я создал отдельные страницы для каждой категории (Статьи и Блог), которые содержат список записей, а также отдельную страницу с категориями форума. Каждый элемент меню выделен классом current-menu-item, и это работает хорошо, когда я открываю страницы Статьи, Блог или Форум. Но когда я открываю запись, связанную с категориями, или когда я открываю тему на форуме, элемент меню теряет свой выделенный класс current-menu-item.

Я пробовал много подходов, найденных в Google, но ни один из них не сработал для меня… вероятно, потому что я не очень знаком с JS и PHP, и что-то упускаю :p

Любая помощь будет очень appreciated.

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

Единственное prerequisite — это то, что категория должна присутствовать в URL, так что измените это в своих постоянных ссылках в настройках.

Внесите изменения, чтобы это применялось к структуре HTML вашей темы, но общая идея остается той же:

function highLightMenu() {

    let url = window.location.href;
    let elements = document.getElementsByClassName("menu-item");
    
    for(let i=0; i<elements.length; i++) { 

        let element = elements[i];
        if(!element || !element.innerText) {
            continue;
        }
        // WordPress конвертирует меню в строчные буквы и разделяет их символом -. "Кейс-стадис" становится "case-studies"
        let title = element.innerText.toLowerCase();
        title = title.replaceAll(" ", "-");
        
        console.log(url + " indexOf " + title);
        if (url.indexOf(title) > -1) {
            // Замените своим классом выделения
            elements[i].classList.add("current-menu-item");
        } 

    }
    
}
highLightMenu();

Фильтр nav_menu_css_class может быть использован для добавления CSS классов к элементам списка, поэтому добавьте необходимую логику, а затем добавьте класс (протестировано):

add_filter( 'nav_menu_css_class', static function ( $classes, $menu_item ) {
    // Добавить класс, если пост принадлежит категории в меню навигации.
    if ( 'taxonomy' === $menu_item->type && 'category' === $menu_item->object && in_category( $menu_item->object_id ) ) {
        $classes[] = 'current-menu-item';
    }

    return $classes;
}, 10, 2 );

Да! Найдено решение, которое хорошо работает в моем случае 🙂

if(window.location.href.indexOf("/blog/") > -1) {
   $('#menu-item-339').addClass('current-menu-item');
}
if(window.location.href.indexOf("/articles/") > -1) {
   $('#menu-item-241').addClass('current-menu-item');
}
if(window.location.href.indexOf("/forum/") > -1) {
   $('#menu-item-437').addClass('current-menu-item');
}

Решение найдено здесь

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

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

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

Самый чистый способ – применить фильтр nav_menu_css_class, который позволяет добавлять классы CSS к элементам списка меню на основании логики, определяющей, находитесь ли вы на странице, связанной с элементом меню.

add_filter('nav_menu_css_class', function($classes, $menu_item) {
    // Проверка на тип таксономии и категорию
    if ('taxonomy' === $menu_item->type && 'category' === $menu_item->object && in_category($menu_item->object_id)) {
        $classes[] = 'current-menu-item';
    }

    return $classes;
}, 10, 2);

Этот код добавляет класс current-menu-item к элементам меню, если вы находитесь на странице поста, относящемуся к соответствующей категории, что обеспечит выделение текущего элемента меню.

2. Использование JavaScript для выделения меню

Как альтернатива, вы можете использовать JavaScript для динамического добавления класса к элементам меню в зависимости от URL. Вот актуальный пример:

function highlightMenu() {
    let url = window.location.href;
    let elements = document.getElementsByClassName("menu-item");

    for(let i = 0; i < elements.length; i++) {
        let element = elements[i];
        if (!element || !element.innerText) {
            continue;
        }

        let title = element.innerText.toLowerCase().replaceAll(" ", "-");

        if (url.indexOf(title) > -1) {
            elements[i].classList.add("current-menu-item");
        } 
    }
}

highlightMenu();

Этот скрипт будет проходить по всем элементам меню и добавлять класс current-menu-item к тому элементу, название которого содержится в текущем URL.

3. Специфические условия для URL

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

if (window.location.href.indexOf("/blog/") > -1) {
    $('#menu-item-339').addClass('current-menu-item');
}
if (window.location.href.indexOf("/articles/") > -1) {
    $('#menu-item-241').addClass('current-menu-item');
}
if (window.location.href.indexOf("/forum/") > -1) {
    $('#menu-item-437').addClass('current-menu-item');
}

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

Заключение

Каждое из этих решений будет эффективным, но использование PHP через nav_menu_css_class предоставит более чистый и устойчивый подход к выделению текущего элемента меню. JavaScript решений подойдут, если вам необходимо быстрое развитие или если у вас есть специфические требования.

Если у вас возникнут дополнительные вопросы или нужны будут уточнения, не стесняйтесь обращаться!

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

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