Добавление выпадающего меню с помощью add_filter => wp_nav_menu_items в WordPress

23 мая 2017 г., 20:53:47
Просмотры: 3.98K
Голосов: 1

Мой проект: WordPress, WooCommerce, Bootstrap 4, bs4navwalker

Моя проблема: Пользовательский элемент выпадающего меню, добавляемый через фильтр WP. У меня есть одна навигационная панель, 3 разных меню (с использованием bs4navwalker), значок корзины и форма поиска. Смотрите код.

Я использую фильтр (add_filter('wp_nav_menu_items',) для добавления входа, выхода и данных аккаунта в мою навигационную панель, все работает, но я хотел бы добавить эти элементы в выпадающее меню. Фильтр просто создает один или два дополнительных элемента в меню 'user'.

Я понимаю, что это происходит потому, что я добавляю <li>, но я не смог понять, как добавить весь код, необходимый Bootstrap для управления выпадающим меню.

Возможно ли это?

Код front-page.php

<div class="nav-custom">
  <div class="container">
    

      <nav class="navbar-nav navbar-toggleable-sm navbar-inverse">

        

        <a class="navbar-brand" href="<?php echo get_home_url(); ?>">
              <img src="<?php bloginfo('template_url'); ?>/img/logo.png" class="d-inline-block align-top" alt="Логотип сайта" title="Логотип">
        </a>

           <?php
           wp_nav_menu([
             'menu'            => 'top',
             'theme_location'  => 'top',
             'container'       => false,
             'container_id'    => 'bs4navbar',
             'container_class' => 'collapse navbar-collapse',
             'menu_id'         => false,
             'menu_class'      => 'navbar-nav mr-auto no-md-view',
             'depth'           => 2,
             'fallback_cb'     => 'bs4navwalker::fallback',
             'walker'          => new bs4navwalker()
           ]);

          ?>
        
        <!-- Форма поиска -->
        <?php get_product_search_form(); ?>

        <!-- Меню пользователя -->
        <?php 
          wp_nav_menu([
           'menu'            => 'user',
           'theme_location'  => 'user',
           'container'       => false,
           //'container_id'    => 'bs4navbar',
           //'container_class' => 'collapse navbar-collapse',
           'menu_id'         => false,
           'menu_class'      => 'navbar-nav mr-auto no-md-view',
           'depth'           => 2,
           'fallback_cb'     => 'bs4navwalker::fallback',
           'walker'          => new bs4navwalker()
         ]);
        ?>

        <!-- Меню корзины -->
        <?php 
          wp_nav_menu([
           'menu'            => 'Cart',
           'theme_location'  => 'Cart',
           'container'       => false,
           //'container_id'    => 'bs4navbar',
           //'container_class' => 'collapse navbar-collapse',
           'menu_id'         => false,
           'menu_class'      => 'navbar-nav mr-auto',
           'depth'           => 2,
           'fallback_cb'     => 'bs4navwalker::fallback',
           'walker'          => new bs4navwalker()
         ]);
        ?>
                <!-- Код для значка START-->
        <?php
        if ( WC()->cart->get_cart_contents_count() !== 0 ) {
        // Делаем что-то интересное
          ?>  
          <span class="badge badge-pill badge-warning no-md-view">
            <a class="cart-customlocation" href="<?php echo wc_get_cart_url(); ?>" title="<?php _e( 'Просмотр корзины' ); ?>"><?php echo sprintf ( _n( '%d товар', '%d товаров', WC()->cart->get_cart_contents_count() ), WC()->cart->get_cart_contents_count() ); ?></a>
          <?php 
        }
        ?>

        </span>
    </nav>

  </div>
</div>

Код functions.php

<?php

add_filter( 'wp_nav_menu_items', 'my_account_loginout_link', 10, 2 );
/**
 * Добавляем вход/выход WooCommerce My Account в меню
 * 
 * @see https://support.woothemes.com/hc/en-us/articles/203106357-Add-Login-Logout-Links-To-The-Custom-Primary-Menu-Area
 */
function my_account_loginout_link( $items, $args ) {
    if (is_user_logged_in() && $args->theme_location == 'user') { //измените расположение меню в теме по необходимости

        
        $items .= '                 
                    <li><a class="nav-link" href="' . get_permalink( wc_get_page_id( 'myaccount' ) ) . '">Мои данные</a></li>
                    <li><a class="nav-link" href="'. wp_logout_url( get_home_url() ) .'">Выход</a></li>
                    '; //измените ссылку выхода, здесь она ведет на 'shop', вы можете направить на 'myaccount'
    }
    elseif (!is_user_logged_in()  && $args->theme_location == 'user') {//измените расположение меню в теме по необходимости
        
     

        $items .= '<li><a class="nav-link" href="' . get_permalink( wc_get_page_id( 'myaccount' ) ) . '">Вход</a></li>';
    }
    return $items;
}

Результат

Как видите, элемент был добавлен в мое меню пользователя (иконка пользователя + Вход), но не как выпадающее меню.

Результат добавления элемента в меню без выпадающего списка

1
Комментарии

Возможно, вам стоит рассмотреть стратегию, которая предполагает добавление элементов как объектов вместо HTML: https://teleogistic.net/2013/02/11/dynamically-add-items-to-a-wp_nav_menu-list/

brianjohnhanna brianjohnhanna
23 мая 2017 г. 21:50:20
Все ответы на вопрос 1
3

Думаю, это реализует то, что вам нужно. По сути, таким образом вы подключаетесь перед генерацией HTML, чтобы добавить свои пункты меню. Я не тестировал этот код, но он должен работать.

РЕДАКТИРОВАНО: Поскольку вы хотите разместить элементы под выпадающим меню, вам нужно установить menu_item_parent. Если пункт меню пользователя остается статичным, вы можете получить ID элемента навигационного меню, посмотрев исходный код этого пункта меню и взяв число, которое следует после menu-item- в ID.

Пример ID элемента меню

Например, в этом случае 103191 — это ID элемента навигационного меню (обратите внимание, что это не то же самое, что ID объекта/записи/страницы/CPT и т.д., на который указывает пункт меню).

function my_account_loginout_link( $items, $menu, $args ) {
    // Проверяем, что это нужное место меню
    if ( $args->theme_location !== 'user' ) {
        return $items;
    }

    // Для авторизованных пользователей
    if ( is_user_logged_in() ) {
        $added_menu_items = array(
            array(
                'title' => 'Мои данные',
                'url' => get_permalink( wc_get_page_id( 'myaccount' ) )
            ),
            array(
                'title' => 'Выйти',
                'url' => wp_logout_url( get_home_url() )
            )
        );
    } else {
        // Для неавторизованных пользователей
        $added_menu_items = array(
            array(
                'title' => 'Войти',
                'url' => get_permalink( wc_get_page_id( 'myaccount' ) )
            )
        );
    }

    $parent_menu_id = 103191; // ID родительского пункта меню
    $menu_order = count( $items ) + 1;
    foreach ( $added_menu_items as $added_item ) {
        $nav_menu_item = new stdClass;
        $nav_menu_item->menu_item_parent = $parent_menu_id;
        $nav_menu_item->url = $added_item['url'];
        $nav_menu_item->title = $added_item['title'];
        $nav_menu_item->menu_order = $menu_order;
        $items[] = $nav_menu_item;
        $menu_order++;
    }
    return $items;
}
add_filter( 'wp_get_nav_menu_items', 'my_account_loginout_link', 10, 3 );

Адаптировано из:

23 мая 2017 г. 22:09:14
Комментарии

Привет, чувак, спасибо за ответ. Я действительно это ценю. Но это не сработало как надо. Элементы были добавлены, но не в нужном месте. Я что-то сделал не так. После этого я решил объяснить немного больше о своем проекте. Может быть, ты сможешь помочь мне это исправить. Смотри правку. Спасибо @brianjohnhanna

Állan Fidelis Toledo Állan Fidelis Toledo
24 мая 2017 г. 14:35:11

Я добавил правку, дай мне знать, если это поможет решить твою проблему

brianjohnhanna brianjohnhanna
24 мая 2017 г. 22:03:23

Спасибо еще раз, но это не сработало. В первый раз ничего не произошло. Сравнивая с другим меню, у которого похожая структура, так как у него нет Dropdown, класс также отсутствовал. Я добавил элемент просто чтобы изменить статус, но ничего не появилось. Кстати, menu_id - 106.

Állan Fidelis Toledo Állan Fidelis Toledo
25 мая 2017 г. 05:44:53