Как использовать элементы кнопок для элементов меню WordPress?

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

Как мне смешать типы HTML-элементов для навигационной панели с двумя меню?

Я создаю тему WordPress с Bootstrap 4.

Содержимое меню WordPress должно извлекаться из параметров меню, выводиться в навигационной панели Bootstrap 4. Я использую этот специальный для Bootstrap 4 wp_nav_menu navwalker

require_once get_template_directory() . '/inc/bs4navwalker.php';

… чтобы вывести основное меню текстовых ссылок навигации в виде ненумерованного списка, так как Бог задумал

 <!-- Navbar https://getbootstrap.com/docs/4.1/components/navbar/ -->
 <nav class="navbar navbar-expand-md navbar-light"><!-- collapse at stated breakpoint -->
     <a class="navbar-brand" href="https://wordpress.stackexchange.com/questions/311941/<?php echo esc_url( home_url("https://wordpress.stackexchange.com/" ) ); ?>">
       <img src="https://www.example.com/logo.gif" height="30" class="d-inline-block align-top mr-1">
       <?php bloginfo( 'name' ); ?>
     </a>
     <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#bs4navbar" aria-controls="bs4navbar" aria-expanded="false" aria-label="Toggle navigation">
       <span class="navbar-toggler-icon"></span>
     </button>
     <?php
     wp_nav_menu([ // bs4navwalker menu generator
       'menu'            => 'primary', // имя меню WordPress
       'theme_location'  => 'primary',
       'depth'           => 2,
       // <nav>:
       // 'container'       => 'false',
       'container_id'    => 'bs4navbar',
       'container_class' => 'collapse navbar-collapse',
       // <ul>:
       'menu_id'         => false,
       'menu_class'      => 'navbar-nav ml-auto',
       // другое:
       'fallback_cb'     => 'bs4navwalker::fallback',
       'walker'          => new bs4navwalker()
     ]);
     ?>
     <button class="btn btn-outline-primary mx-3" type="submit">Кнопка</button>
     <button class="btn btn-primary ml-3" type="submit">Записаться</button>
 </nav>

Это работает отлично. Вывод…

введите описание изображения здесь

<nav class="navbar navbar-expand-md navbar-light"><!-- collapse at stated breakpoint -->
     <a class="navbar-brand" href="http://www.example.com/">
       <img src="https://www.example.com/logo.gif" height="30" class="d-inline-block align-top mr-1">
              Песочница     </a>
     <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#bs4navbar" aria-controls="bs4navbar" aria-expanded="false" aria-label="Toggle navigation">
       <span class="navbar-toggler-icon"></span>
     </button>
     <div id="bs4navbar" class="collapse navbar-collapse">
       <ul id="menu-my-menu" class="navbar-nav ml-auto">
         <li id="menu-item-3" class="menu-item menu-item-type-custom menu-item-object-custom current-menu-item current_page_item menu-item-home menu-item-3 nav-item mx-3 active"><a title="Главная страница" href="http://sandbox.contexthq.com/" class="nav-link active" aria-expanded="false"><i class="icon-speedometer"></i>Главная</a></li>
         <li id="menu-item-4" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-4 nav-item mx-3"><a title="Пример страницы" href="http://example.com/" class="nav-link" aria-expanded="false"><i class="ti-layout-grid2"></i>Тренды</a></li>
         <li id="menu-item-5" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-5 nav-item mx-3"><a title="Пользовательская страница" href="http://example.com/custom/" class="nav-link" aria-expanded="false"><i class="ti-palette"></i>Пользовательская</a></li>
         <li id="menu-item-14" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-14 nav-item mx-3"><a href="#" class="nav-link" aria-expanded="false">Стратегия</a></li>
       </ul>
     </div>
     <button class="btn btn-outline-primary mx-3" type="submit">Кнопка</button>
     <button class="btn btn-primary ml-3" type="submit">Записаться</button>
 </nav>

Тем не менее, вы увидите часть, в которой я вручную вставил два <button> элемента. Вместо жесткого кода я хочу, чтобы они генерировались динамически из меню WordPress, так же как и меню primary.

Я создал второе меню WordPress, buttons. Вот здесь я разбираюсь…

Я могу вставить второй вызов wp_nav_menu для buttons, сразу после первого для primary

 <?php
 wp_nav_menu([ // генератор меню bs4navwalker
   'menu'            => 'buttons', // имя меню WordPress
   'theme_location'  => 'buttons',
   'depth'           => 2,
   // <nav>:
   // 'container'       => 'false',
   'container_id'    => 'bs4navbar',
   'container_class' => 'collapse navbar-collapse',
   // <ul>:
   'menu_id'         => false,
   'menu_class'      => 'navbar-nav ml-auto',
   // другое:
   'fallback_cb'     => 'bs4navwalker::fallback',
   'walker'          => new bs4navwalker()
 ]);
 ?>

… и элементы меню будут вставлены в нужное место.

Проблема в том, что эти элементы – <li> внутри <ul>, так же как и меню primary

введите описание изображения здесь

Я предполагаю, что bs4navwalker настроен на вывод всех элементов wp_nav_menu как элементов списка, или, может быть, это дело WordPress.

Как я могу сделать так, чтобы элементы из второго меню, buttons, выводились с использованием другой HTML-структуры, вместо этого как элементы <button>?

Следующее решение, хотя и требует дополнительной обработки PHP…

 <?php

 $options =  array(
     'echo'              => false,
     'theme_location'    => 'buttons',
     'items_wrap'        => '%3$s',
     'menu_class'        => false,
     'menu_id'           => false,
     'container'         => 'false',
     'container_class'   => false,
     'container_id'      => false,
     'before'            => '<button class="btn btn-primary mx-3 d-none d-md-block" type="submit">',
     'after'             => '</button>'
 );

 $menu = wp_nav_menu($options);

 $output = strip_tags($menu, '<button>');

 echo preg_replace('/btn-primary/', 'btn-outline-primary', $output, 1);

 ?>

Это включает в себя:

  • Удаление <ul>
  • Не создание контейнеров
  • Оборачивание каждого элемента в тег <button>
  • Подавление вывода
  • Удаление всех тегов (т.е. <li>), за исключением <button>)
  • В последней части замена первого экземпляра класса btn-primary на btn-outline-primary, чтобы сохранить кнопки двух цветов.

Вот вывод…

введите описание изображения здесь

<button class="btn btn-outline-primary mx-3 d-none d-md-block" type="submit">Кнопка</button>
<button class="btn btn-primary mx-3 d-none d-md-block" type="submit">Узнать больше</button>

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

Есть ли способ сделать так, чтобы эти классы появлялись в элементе навигации, вместо использования preg_replace, или этот метод не поддержит это?

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

Как использовать элементы кнопок для элементов меню WordPress

Создание адаптивного и функционального навигационного меню с использованием WordPress и Bootstrap 4 — это задача, которая требует координированного подхода как к дизайну, так и к коду. В данном руководстве мы рассмотрим, как динамически генерировать элементы меню в виде кнопок, вытаскивая их из настроек меню WordPress.

1. Реализация второго меню

Ваша цель состоит в том, чтобы создать второе меню (например, buttons), элементы которого будут отображаться в виде кнопок вместо стандартных ссылок. Начнем с его создания в админ-панели WordPress:

  • Перейдите в Внешний вид -> Меню.
  • Создайте новое меню с именем buttons и добавьте нужные пункты.

2. Написание кода для отображения меню

Теперь вам нужно обновить файл темы (например, header.php) для корректного отображения как основного меню, так и кнопочного меню.

Вот как можно это сделать:

<nav class="navbar navbar-expand-md navbar-light">
    <a class="navbar-brand" href="<?php echo esc_url(home_url()); ?>">
        <img src="https://www.example.com/logo.gif" height="30" class="d-inline-block align-top mr-1">
        <?php bloginfo('name'); ?>
    </a>
    <!-- Кнопка для мобильной навигации -->
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#bs4navbar" aria-controls="bs4navbar" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
    </button>

    <!-- Основное меню -->
    <?php
    wp_nav_menu([
        'menu'            => 'primary',
        'theme_location'  => 'primary',
        'depth'           => 2,
        'container'       => false,
        'menu_class'      => 'navbar-nav ml-auto',
        'walker'          => new bs4navwalker()
    ]);
    ?>

    <!-- Динамическое кнопочное меню -->
    <?php
    $options =  array(
        'echo'              => false,
        'theme_location'    => 'buttons',
        'items_wrap'        => '%3$s',
        'menu_class'        => false,
        'menu_id'           => false,
        'container'         => false,
        'before'            => '<button class="btn btn-primary mx-3" type="submit">',
        'after'             => '</button>'
    );

    // Получаем меню в виде кнопок
    $menu = wp_nav_menu($options);
    // Удаляем все теги, кроме <button>
    $output = strip_tags($menu, '<button>');
    echo $output;
    ?>
</nav>

3. Пояснение кода

  • Регистрация второго меню: Убедитесь, что вы зарегистрировали оба меню в файле функций вашей темы (functions.php):
register_nav_menus([
    'primary' => __('Primary Menu'),
    'buttons' => __('Buttons Menu')
]);
  • Dynamically Generated Buttons: Код, который мы использовали для кнопочного меню, позволяет оборачивать каждый элемент меню WordPress в тег <button>. Это делается с помощью параметров before и after, которые добавляют классы Bootstrap, а также другие атрибуты.

4. Гибкость управления классами кнопок

Для того чтобы вам не приходилось жестко кодировать классы кнопок (такие как btn-primary), их можно задавать в админ панели WordPress через настройки для каждого элемента меню. Однако, если это не поддерживается напрямую в WordPress, то можно добавить соответствующее поле для настройки классов в интерфейсе редактирования элементов меню, что позволит динамически генерировать стили кнопок:

add_filter('nav_menu_item_attributes', function($atts, $item) {
    // Здесь можно добавить логику для установки классов кнопок
    $atts['class'] = get_post_meta($item->ID, 'button_class', true);
    return $atts;
}, 10, 2);

Заключение

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

Не забывайте всегда сохранять резервные копии вашего кода и тестировать изменения на локальном сервере перед их внедрением на боевом сайте.

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

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