WordPress. Меню навигации. Часть 1 из 2

25.03.2019

Теги: CMSWeb-разработкаWordPressМенюНавигация

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

Включаем поддержку произвольных меню

Для начала нужно зарегистрировать возможность использования произвольных меню. Для этого добвляем в файл functions.php вызов функции register_nav_menu() или register_nav_menus().

Функция register_nav_menu()

Регистрирует одно расположение меню, к которому затем в админке прикрепляется меню. Меню выводится в шаблоне функцией wp_nav_menu().

register_nav_menu($location, $description);
  • $location (строка, обязательный). Идентификатор расположения меню.
  • $description (строка, обязательный). Описание расположения меню, которое будет показываться в админке.

Функцию принято вызывать во время события after_setup_theme. Чтобы зарегистрировать сразу несколько расположений, можно использовать функцию register_nav_menus().

// пример регистрации двух меню
add_action(
    'after_setup_theme',
    function() {
        register_nav_menu('header_menu', 'Меню в шапке');
        register_nav_menu('footer_menu', 'Меню в подвале');
    }
);

Функция автоматически регистрирует поддержку навигационных меню для темы. При использовании этой функции нет необходимости предварительно вызывать функцию:

add_theme_support('menus');

Функция register_nav_menus()

Регистрирует сразу несколько расположений меню, к которым затем в админке прикрепляются меню. Меню выводятся в шаблоне функцией wp_nav_menu().

register_nav_menus($locations);
  • $locations (массив, обязательный). Массив с идентификаторами (ключи массива) и описаниями (значения ключей) каждого создаваемого меню.

Функцию принято вызывать во время события after_setup_theme. Чтобы зарегистрировать только одно расположение, можно использовать функцию register_nav_menu().

// пример регистрации двух меню
add_action(
    'after_setup_theme',
    function() {
        register_nav_menus([
            'header_menu' => 'Меню в шапке',
            'footer_menu' => 'Меню в подвале'
        ]);
    }
);

Функция автоматически регистрирует поддержку навигационных меню для темы. При использовании этой функции нет необходимости предварительно вызывать функцию:

add_theme_support('menus');

Создаем произвольные меню

После того, как меню зарегистрированы, идем в панель управления и создаем свои меню. Связь между меню и расположением — «один-ко-многим». Т.е. одно меню может быть привязано к нескольким расположениям. Но к одному расположению может быть привязано только одно меню.

Вывод произвольных меню

Меню зарегистрированы и созданы, осталось добавить их в шаблон с помощью функции wp_nav_menu().

Функция wp_nav_menu()

Выводит произвольное меню, созданное в панели: «Внешний вид • Меню». Какое именно меню навигации выводить, указывается в параметре theme_location или menu.

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

add_theme_support('menus');

Или можно зарегистрировать место для меню, с помощью register_nav_menu(), тогда поддержка меню темой включиться автоматически.

wp_nav_menu([
    'theme_location'  => '',
    'menu'            => '', 
    'container'       => 'div', 
    'container_class' => '', 
    'container_id'    => '',
    'menu_class'      => 'menu', 
    'menu_id'         => '',
    'echo'            => true,
    'fallback_cb'     => 'wp_page_menu',
    'before'          => '',
    'after'           => '',
    'link_before'     => '',
    'link_after'      => '',
    'items_wrap'      => '<ul id="%1$s" class="%2$s">%3$s</ul>',
    'depth'           => 0,
    'walker'          => '',
]);
  • theme_location (строка). Идентификатор расположения меню в шаблоне. По умолчанию пустая строка.
  • menu (строка). Меню которое нужно вывести. Соответствие: id, slug или название меню. По умолчанию пустая строка.
  • container (строка/false). Чем оборачивать ul тег. Допустимо: false, div или nav. По умолчанию: 'div'.
  • container_class (строка). Значение атрибута class у контейнера меню. По умолчанию: 'menu-{slug}-container'.
  • container_id (строка). Значение атрибута id у контейнера меню. По умолчанию пустая строка.
  • menu_class (строка). Значение атрибута class у тега ul. По умолчанию: 'menu'.
  • menu_id (строка). Значение атрибута id у тега ul. По умолчанию: 'menu-{slug}'.
  • items_wrap (строка). Шаблон обёртки для элементов меню. Шаблон обязательно должен иметь плейсхолдер %3$s, остальное опционально. По умолчанию: '<ul id="%1$s" class="%2$s">%3$s</ul>'.
  • fallback_cb (строка). Функция для обработки вывода, если никакое меню не найдено. Установите пустую строку, чтобы ничего не выводилось, если меню нет. По умолчанию: 'wp_page_menu'.
  • before (строка). Текст перед тегом <a> в меню. По умолчанию пустая строка.
  • after (строка). Текст после каждого тега </a> в меню. По умолчанию пустая строка.
  • link_before (строка). Текст перед анкором каждой ссылки в меню. По умолчанию пустая строка.
  • link_after (строка). Текст после анкора каждой ссылки в меню. По умолчанию пустая строка.
  • depth (число). Сколько уровеней вложенности показывать. По умолчанию ноль (все уровни).
  • item_spacing (строка). Оставлять или нет переносы строк в HTML коде меню. Может быть: preserve или discard. По умолчанию: preserve.
  • echo (логическое). Выводить на экран (true) или возвратить для обработки (false). По умолчанию: true.
  • walker (объект). Объект класса для построения меню. По умолчанию: объект Walker_Nav_Menu().

Чаще всего для указания, какое меню выводить, используют параметр theme_location:

wp_nav_menu([
    'theme_location'  => 'header_menu'
]);

Но можно использовать и параметр menu:

wp_nav_menu([
    'menu'  => 'Главное меню'
]);

Результат будет одинаковый:

<div class="menu-%d0%b3%d0%bb%d0%b0%d0%b2%d0%bd%d0%be%d0%b5-%d0%bc%d0%b5%d0%bd%d1%8e-container">
    <ul id="menu-%d0%b3%d0%bb%d0%b0%d0%b2%d0%bd%d0%be%d0%b5-%d0%bc%d0%b5%d0%bd%d1%8e" class="menu">
        <li id="menu-item-1911" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-1911">
            <a href="http://www.server.com/about-author/">Об авторе блога</a>
        </li>
        <li id="menu-item-1912" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-1912">
            <a href="http://www.server.com/feedback/">Обратная связь</a>
        </li>
        <li id="menu-item-1913" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-1913">
            <a href="http://www.server.com/test-page/">Тестовая страница</a>
        </li>
        <li id="menu-item-1914" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-1914">
            <a href="https://wp-kama.ru/">Сайт WP-KAMA</a>
        </li>
    </ul>
</div>

Пример создания меню

Допустим, при верстке шаблона был использован фреймворк Bootstrap 4. Чтобы не создавать стили для меню с нуля, нам нужно использовать свой шаблон, с классами bootstrap. Который выглядит так:

<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
    <a class="navbar-brand" href="#">Главная</a>
    <button class="navbar-toggler"
            type="button"
            data-toggle="collapse"
            data-target="#main-menu"
            aria-controls="main-menu"
            aria-expanded="false"
            aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="main-menu">
        <ul class="navbar-nav mr-auto">
            <li class="nav-item active"> <!-- текущая страница -->
                <a class="nav-link" href="#">Link</a>
            </li>
            <li class="nav-item">
                <a class="nav-link" href="#">Link</a>
            </li>
            <li class="nav-item">
                <a class="nav-link disabled" href="#">Disabled</a>
            </li>
        </ul>
    </div>
</nav>

Для начала просто вставим вызов функции и посмотрим, что получилось:

<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
    <a class="navbar-brand" href="<?= home_url(); ?>">Главная</a>
    <button class="navbar-toggler"
            type="button"
            data-toggle="collapse"
            data-target="#main-menu"
            aria-controls="main-menu"
            aria-expanded="false"
            aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
    </button>
    <?php
    wp_nav_menu([
        'theme_location'  => 'header_menu',
        'container'       => 'div',
        'container_class' => 'collapse navbar-collapse',
        'container_id'    => 'main-menu',
        'menu_class'      => 'navbar-nav mr-auto',
        'menu_id'         => 'main-menu-ul',
    ]);
    ?>
</nav>
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
    <a class="navbar-brand" href="http://www.server.com">Главная</a>
    <button class="navbar-toggler"
            type="button"
            data-toggle="collapse"
            data-target="#main-menu"
            aria-controls="main-menu"
            aria-expanded="false"
            aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
    </button>
    <div id="main-menu" class="collapse navbar-collapse">
        <ul id="main-menu-ul" class="navbar-nav mr-auto">
            <li id="menu-item-1911" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-1911">
                <a href="http://www.server.com/about-author/">Об авторе блога</a>
            </li>
            <li id="menu-item-1912" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-1912">
                <a href="http://www.server.com/feedback/">Обратная связь</a>
            </li>
            <li id="menu-item-1913" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-1913">
                <a href="http://www.server.com/test-page/">Тестовая страница</a>
            </li>
            <li id="menu-item-1914" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-1914">
                <a href="https://wp-kama.ru/">Сайт WP-KAMA</a>
            </li>
        </ul>
    </div>
</nav>

Не хватает класса nav-item для элементов <li> и класса nav-link для элементов <a>. Давайте это исправим.

Класс nav-item для элементов <li> можно добавить в панели управления. Для этого отмечаем checkbox «Классы CSS» в настройках экрана и добавляем для каждого элемента меню класс nav-item:

Но выглядит это не очень красиво — нам нужен только один CSS-класс, а у нас целых пять. Да и как задать класс active для текущей страницы? Поэтому добавляем в файл functions.php следующий код:

add_filter(
    'nav_menu_css_class',
    function($classes, $item) {
        /*
         * Переменная $classes содержит
         * Array(
         *   [1] => menu-item
         *   [2] => menu-item-type-post_type
         *   [3] => menu-item-object-page
         *   [4] => menu-item-1911
         * )
         */
        // переопределяем переменную $classes
        $classes = [1 => 'nav-item'];
        if ($item->current) {
            // добавляем класс active для текущей страницы
            $classes[2] = 'active';
        }
        return $classes;
    },
    10,
    2
);

Осталось только добавить класс nav-link для элементов <a>:

add_filter(
    'nav_menu_link_attributes',
    function($atts, $item, $args, $depth) {
        // добавляем класс nav-link для элементов <a>
        $atts['class'] = 'nav-link';
        return $atts;
    },
    10,
    4
);

И получаем в результате то, что нам нужно:

<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
    <a class="navbar-brand" href="http://www.server.com">Главная</a>
    <button class="navbar-toggler"
            type="button"
            data-toggle="collapse"
            data-target="#main-menu"
            aria-controls="main-menu"
            aria-expanded="false"
            aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
    </button>
    <div id="main-menu" class="collapse navbar-collapse">
        <ul id="main-menu-ul" class="navbar-nav mr-auto">
            <li id="menu-item-1911" class="nav-item active">
                <a href="http://www.server.com/about-author/" class="nav-link">Об авторе блога</a>
           </li>
            <li id="menu-item-1912" class="nav-item">
                <a href="http://www.server.com/feedback/" class="nav-link">Обратная связь</a>
            </li>
            <li id="menu-item-1913" class="nav-item">
                <a href="http://www.server.com/test-page/" class="nav-link">Тестовая страница</a>
            </li>
            <li id="menu-item-1914" class="nav-item">
                <a href="https://wp-kama.ru/" class="nav-link">Сайт WP-KAMA</a>
            </li>
        </ul>
    </div>
</nav>

Поиск: CMS • Web-разработка • WordPress • Меню • Навигация • register_nav_menu • register_nav_menus • add_theme_support • wp_nav_menu • Bootstrap

Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.