Меню WordPress: как настроить навигацию, создать выпадающее меню и вывести в любом месте

Меню WordPress: как настроить навигацию, создать выпадающее меню и вывести в любом месте

Краткий ответ: меню WordPress создаётся в админке в разделе «Внешний вид → Меню»: задайте имя меню, добавьте страницы, рубрики или произвольные ссылки и привяжите меню к области вывода (theme location), которую зарегистрировала тема через register_nav_menus(). Выводится меню функцией wp_nav_menu() — её можно вызвать в любом месте темы: в шапке, подвале, сайдбаре. Выпадающее меню делается из вложенных пунктов (перетаскивание с отступом) и оформляется CSS и небольшим скриптом.

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

В этом практическом гайде мы разберём всё по порядку: как устроено меню внутри WordPress, как создать его в админке, как сделать выпадающие подменю, как зарегистрировать область меню в теме через register_nav_menus() и вывести меню в любом месте с помощью wp_nav_menu(). Также покажем, как добавлять пункты меню программно и как работают walker-классы. Материал рассчитан на разработчиков-новичков, поэтому все примеры даны с готовым кодом, который можно скопировать в свою тему.

Как устроено меню в WordPress: основные понятия

Меню WordPress хранится не в шаблоне, а в базе данных. Архитектурно каждое меню — это термин таксономии nav_menu, а каждый пункт меню — запись типа nav_menu_item со своими мета-полями: ссылка, заголовок, родитель, порядок, CSS-классы. Благодаря этому меню можно создавать и редактировать из админки, не трогая код темы.

Чтобы ориентироваться в теме, запомните четыре термина:

  • Пункт меню (menu item) — отдельная ссылка в меню: на страницу, рубрику, запись или произвольный URL.
  • Область меню (menu location) — заранее зарегистрированное темой место, куда можно назначить меню. Например, «Главное меню», «Меню в подвале», «Мобильное меню».
  • Fallback — запасной вариант вывода: если в область не назначено ни одно меню, WordPress может показать список страниц или ничего.
  • Walker — класс, который формирует HTML-разметку пунктов меню. По умолчанию используется Walker_Nav_Menu, но тему можно научить выводить пункты по-своему.

Ключевой момент, который снимает половину вопросов новичков: создать меню в админке и назначить его на область — это два разных действия. Можно создать хоть десять меню, но если ни одно не назначено в зарегистрированную областью тему — на сайте ничего не появится. О том, как тема регистрирует области, мы поговорим в разделе про register_nav_menus(), а пока разберём создание меню в админке.

Создание меню в админке WordPress: пошаговая инструкция

Классический способ создать меню — через консоль. Зайдите в «Внешний вид → Меню» и выполните несколько шагов.

  1. Дайте меню имя (например, «Главное меню») и нажмите «Создать меню».
  2. Добавьте элементы. В левой колонке доступны вкладки «Страницы», «Произвольные ссылки» и «Рубрики». Отметьте нужные пункты галочками и нажмите «Добавить в меню». Для произвольной ссылки впишите URL и текст ссылки.
  3. Расставьте порядок. Пункты перетаскиваются мышью: выше — ближе к началу. Чтобы сделать подпункт (для выпадающего меню), перетащите его чуть правее родительского пункта — появится отступ.
  4. Назначьте область отображения. Внизу экрана (или на вкладке «Области меню») отметьте галочкой, в какие области темы вывести меню — например, «Главное меню».
  5. Сохраните меню кнопкой «Сохранить меню».

Полезная настройка — галочка «Автоматически добавлять новые страницы» (внизу, для верхнего уровня меню). Если вы часто публикуете новый контент, WordPress будет сам добавлять новые страницы в конец меню — не придётся делать это вручную.

Кстати, меню можно выводить не только в назначенных областях, но и в виджете «Произвольное меню» — его добавляют в сайдбар или подвал. Подробнее про виджеты и области вывода читайте в нашей статье про настройку виджетов и сайдбаров WordPress.

Выпадающее меню WordPress: CSS и JS

Выпадающее (dropdown) меню — стандарт для многоуровневой навигации. Сделать его в WordPress несложно, потому что движок уже умеет выводить вложенные пункты: если в админке перетащить пункт под родительский, в разметке появится вложенный список <ul class="sub-menu">. Остаётся только «научить» его показываться при наведении или клике.

Шаг 1. Создайте вложенность в админке, как описано выше: «О нас» → подпункты «Команда», «Вакансии», «Контакты».

Шаг 2. Добавьте CSS. Базовый вариант — показывать подменю при наведении курсора и при фокусе с клавиатуры:

/* Скрываем подменю по умолчанию */
.main-menu ul.sub-menu {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    min-width: 220px;
    background: #ffffff;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
    z-index: 999;
}

/* Показываем при наведении на родительский пункт */
.main-menu li:hover > ul.sub-menu,
.main-menu li:focus-within > ul.sub-menu {
    display: block;
}

/* Подменю третьего уровня открываем вправо */
.main-menu ul.sub-menu ul.sub-menu {
    top: 0;
    left: 100%;
}

:focus-within — обязательный атрибут хорошего кода: он делает выпадающее меню доступным для людей, которые пользуются клавиатурой, а это положительно влияет и на поведенческие факторы.

Шаг 3. Добавьте JavaScript — для мобильных устройств, где нет наведения, и для закрытия подменю по клику вне меню. Простой вариант на чистом JS:

// Раскрытие подменю по клику на родительский пункт
document.querySelectorAll('.main-menu li.menu-item-has-children > a').forEach(function (link) {
    link.addEventListener('click', function (e) {
        var li = link.parentElement;
        var sub = li.querySelector(':scope > ul.sub-menu');
        if (!sub) return;
        e.preventDefault();
        var isOpen = sub.style.display === 'block';
        closeAllMenus();
        if (!isOpen) {
            sub.style.display = 'block';
            li.classList.add('menu-open');
        }
    });
});

function closeAllMenus() {
    document.querySelectorAll('.main-menu ul.sub-menu').forEach(function (sub) {
        sub.style.display = 'none';
    });
    document.querySelectorAll('.main-menu li.menu-open').forEach(function (li) {
        li.classList.remove('menu-open');
    });
}

// Закрытие меню по клику в любом другом месте страницы
document.addEventListener('click', function (e) {
    if (!e.target.closest('.main-menu')) {
        closeAllMenus();
    }
});

Способы реализации выпадающих меню удобно сравнить в таблице:

Способ Плюсы Минусы Когда применять
Чистый CSS (:hover) Минимум кода, работает без JS, быстро Не раскрывается по тапу на сенсорных экранах Классические десктопные сайты
CSS :focus-within Доступно с клавиатуры, без JS Требует аккуратной разметки и проверки в браузерах Базовый уровень доступности на любых сайтах
JavaScript (vanilla / jQuery) Клик по тапу, анимации, закрытие по клику вне Больше кода, нужна обработка «гонки» открытых меню Мобильные меню, бургеры, сложная навигация
Плагин (Max Mega Menu и аналоги) Готовые стили, мегаменю, конструктор без кода Лишняя нагрузка, зависимость от плагина Большие каталоги и интернет-магазины

Для большинства проектов достаточно связки CSS-хover + небольшой JS для мобильных. Плагины с мегаменю оправданы, когда в подменю нужно выводить карточки товаров, изображения и виджеты.

Регистрация областей меню в теме: register_nav_menus

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

<?php
add_action('after_setup_theme', function () {
    register_nav_menus(array(
        'primary' => 'Главное меню (шапка)',
        'footer'  => 'Меню в подвале',
        'mobile'  => 'Мобильное меню',
    ));
});

Ключ массива (например, primary) — это уникальный идентификатор области, по которому вы будете обращаться к ней при выводе. Значение — название, которое увидит пользователь в админке на экране «Внешний вид → Меню».

Если областей в теме мало и нужна всего одна, можно использовать функцию register_nav_menu():

<?php
add_action('after_setup_theme', function () {
    register_nav_menu('primary', 'Главное меню');
});

Для локализации темы названия областей оборачивают в __():

<?php
register_nav_menus(array(
    'primary' => __('Главное меню', 'mytheme'),
));

После добавления кода обновите страницу «Внешний вид → Меню»: в блоке назначения появятся новые области. Не забывайте, что любые изменения лучше делать в дочерней теме WordPress, иначе правки потеряются при обновлении родительской темы.

Вывод меню в любом месте темы: wp_nav_menu

За вывод меню отвечает функция wp_nav_menu(). Её можно вызвать в любом файле шаблона — в header.php, footer.php, sidebar.php, в виджете или через хук. Базовый вызов с областью primary выглядит так:

<?php
wp_nav_menu(array(
    'theme_location' => 'primary',
    'container'      => 'nav',
    'container_class'=> 'main-menu-wrap',
    'menu_class'     => 'main-menu',
    'fallback_cb'    => false,
));

Разберём главные параметры wp_nav_menu() в таблице:

Параметр Значение по умолчанию Назначение
theme_location пусто Идентификатор области, назначенной в админке. Если пусто — ищет меню по параметру menu
menu пусто ID, slug или название конкретного меню для вывода «напрямую»
container div Тег-обёртка вокруг списка (nav, div или false для отключения)
container_class / container_id пусто CSS-класс и ID обёртки
menu_class / menu_id menu CSS-класс и ID самого списка <ul>
depth 0 (без ограничений) Максимальный уровень вложенности, например 1 — только верхний уровень
fallback_cb wp_page_menu Функция-запасной вариант, если меню не назначено
walker Walker_Nav_Menu Класс, формирующий HTML пунктов
echo true Вывести сразу (true) или вернуть строку (false)
before / after пусто Текст до и после ссылки пункта (например, иконка)
link_before / link_after пусто Текст внутри тега <a> до и после заголовка
items_wrap <ul id="%1$s" class="%2$s">%3$s</ul> Шаблон обёртки списка

Чтобы меню выводилось только тогда, когда оно назначено, добавляют проверку has_nav_menu():

<?php
if (has_nav_menu('primary')) {
    wp_nav_menu(array('theme_location' => 'primary'));
} else {
    // Запасной вариант: простой список страниц
    wp_list_pages(array('title_li' => ''));
}

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

<?php
add_action('wp_footer', function () {
    if (has_nav_menu('footer')) {
        echo '<nav class="footer-menu">';
        wp_nav_menu(array('theme_location' => 'footer'));
        echo '</nav>';
    }
});

Ещё один способ вывода — шорткод: зарегистрируйте короткий код, который вызывает wp_nav_menu(), и вставляйте меню в любую запись или страницу. Как это сделать, показано в нашем руководстве по созданию шорткодов WordPress. А в сайдбаре меню проще всего разместить через виджет «Произвольное меню» — об этом мы писали в статье про виджеты и сайдбары.

Добавление пунктов меню программно: wp_get_nav_menu_items

Иногда пункты меню нужно добавить или изменить кодом: например, показать ссылку «Личный кабинет» только залогиненным пользователям или автоматически подставить пункт с акцией. Для этого используют функцию wp_get_nav_menu_items(), которая возвращает массив пунктов меню.

Получим пункты меню по имени и выведем их своими руками:

<?php
$menu_items = wp_get_nav_menu_items('Главное меню');

if ($menu_items) {
    foreach ($menu_items as $item) {
        // Пропускаем вложенные пункты для простоты примера
        if ($item->menu_item_parent != 0) {
            continue;
        }
        echo '<a href="' . esc_url($item->url) . '">' . esc_html($item->title) . '</a>';
    }
}

У объекта пункта меню доступны свойства: title (заголовок), url (ссылка), ID, menu_item_parent (ID родителя), object_id (ID страницы/записи), classes (массив CSS-классов), target, description.

Чтобы добавить пункт в уже существующее меню, используйте wp_update_nav_menu_item(). Пример: добавить в меню ссылку «Личный кабинет» один раз при активации темы:

<?php
add_action('init', function () {
    // Работаем один раз — защита от дублирования пунктов
    if (get_option('menu_cabinet_added')) {
        return;
    }

    $menu = wp_get_nav_menu_object('Главное меню');
    if (!$menu) {
        return;
    }

    wp_update_nav_menu_item($menu->term_id, 0, array(
        'menu-item-title'  => 'Личный кабинет',
        'menu-item-url'    => home_url('/cabinet/'),
        'menu-item-status' => 'publish',
    ));

    update_option('menu_cabinet_added', 1);
});

А чтобы скрыть или изменить пункты при выводе (не трогая базу данных), используйте фильтр wp_nav_menu_objects. Например, уберём пункт «Личный кабинет» для неавторизованных:

<?php
add_filter('wp_nav_menu_objects', function ($items) {
    if (is_user_logged_in()) {
        return $items;
    }

    foreach ($items as $key => $item) {
        if ($item->title === 'Личный кабинет') {
            unset($items[$key]);
        }
    }

    return $items;
});

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

Walker-классы: как изменить вывод пунктов меню

Walker — это класс WordPress, который рекурсивно обходит пункты меню и собирает HTML. Стандартный Walker_Nav_Menu подходит в 90% случаев, но когда нужно добавить иконки, data-атрибуты, обернуть ссылку в кнопку или переписать разметку под фреймворк — пишут свой walker.

Мини-пример: добавить стрелку-индикатор к пунктам, у которых есть подменю. Класс уже помечает такие пункты классом menu-item-has-children:

<?php
class My_Menu_Walker extends Walker_Nav_Menu {

    public function start_el(&$output, $item, $depth = 0, $args = null, $id = 0) {
        parent::start_el($output, $item, $depth, $args, $id);

        if (in_array('menu-item-has-children', $item->classes)) {
            $output .= '<span class="menu-arrow"></span>';
        }
    }
}

wp_nav_menu(array(
    'theme_location' => 'primary',
    'walker'         => new My_Menu_Walker(),
));

Основные методы walker-класса, которые переопределяют чаще всего:

  • start_lvl() / end_lvl() — открывающий и закрывающий теги вложенного списка <ul class="sub-menu">;
  • start_el() / end_el() — разметка отдельного пункта <li> со ссылкой.

Если вам нужно изменить только пару атрибутов, сначала проверьте, можно ли обойтись фильтрами nav_menu_css_class, nav_menu_link_attributes и wp_nav_menu_objects — это проще, чем писать целый walker. Свой класс стоит создавать, когда меняется сама структура разметки.

Частые проблемы с меню WordPress и их решение

Соберём типичные ситуации, с которыми сталкиваются новички, и их решения.

  • Меню не отображается на сайте. Самая частая причина — меню не назначено в область вывода. Проверьте «Внешний вид → Меню → Области меню» и убедитесь, что галочка стоит. Вторая причина — fallback_cb => false при пустой области: функция просто ничего не выводит. Третья — кэш: сбросьте кэш плагинов и сервера.
  • Выпадающее меню не открывается. Проверьте, что вложенные пункты действительно созданы в админке (отступ у подпунктов) и что в CSS нет overflow: hidden у родительского блока, который «обрезает» подменю. Также проверьте z-index: подменю может оказаться под другими элементами страницы.
  • На мобильных пункты с подменю не открываются. На сенсорных экранах нет наведения, поэтому нужен JavaScript, который раскрывает подменю по клику — пример есть в разделе про выпадающее меню.
  • Пункты пропали после обновления темы. Чаще всего тема сменила идентификаторы областей. Зайдите в «Внешний вид → Меню» и назначьте меню заново. Именно поэтому правки кода делают в дочерней теме.
  • Меню дублируется. Обычно это значит, что wp_nav_menu() вызывается и в шаблоне, и в виджете, или зарегистрировано два места с одинаковым выводом. Проверьте header.php и настройки виджетов.
  • Активный пункт не подсвечивается. Для подсветки используйте CSS-классы .current-menu-item, .current-menu-parent, которые WordPress добавляет автоматически.

Если вы только начинаете разбираться в устройстве WordPress, рекомендуем держать под рукой наши материалы из раздела «Разработка WordPress» — там собраны практические гайды по темам, виджетам, шорткодам и безопасности.

Частые вопросы о меню WordPress

Как создать меню в WordPress?

Зайдите в «Внешний вид → Меню», дайте меню имя и нажмите «Создать меню». Затем добавьте страницы, рубрики или произвольные ссылки, расставьте порядок перетаскиванием и обязательно назначьте меню в одну из областей отображения внизу экрана. После этого сохраните меню.

Как вывести меню в любом месте темы WordPress?

Используйте функцию wp_nav_menu() с параметром theme_location, равным идентификатору зарегистрированной области. Её можно вызвать в любом шаблонном файле (header.php, footer.php, sidebar.php), на хуке (например, wp_footer) или внутри шорткода. Также меню выводится виджетом «Произвольное меню».

Как сделать выпадающее меню в WordPress?

Создайте вложенные пункты в админке, перетащив подпункты правее родительских. WordPress сам выведет их в список ul.sub-menu. Останется добавить CSS, который показывает подменю при наведении или фокусе (:hover, :focus-within), и JavaScript для раскрытия по клику на мобильных устройствах.

Почему меню не отображается на сайте?

Скорее всего, меню не назначено в область отображения — проверьте «Внешний вид → Меню → Области меню». Также проверьте, что в теме зарегистрирована область с тем же идентификатором, что указан в wp_nav_menu(), и сбросьте кэш сайта после изменений.

Как добавить пункт меню программно?

Используйте wp_update_nav_menu_item($menu_id, 0, $args), передав в $args заголовок, URL и статус пункта. Получить существующие пункты можно функцией wp_get_nav_menu_items(), а изменить вывод без изменения базы данных — фильтром wp_nav_menu_objects.

Что такое walker в WordPress?

Walker — это класс, который формирует HTML-разметку списка пунктов меню. Стандартный Walker_Nav_Menu подходит большинству тем; свой класс создают, когда нужно изменить структуру разметки: добавить иконки, data-атрибуты, обёртки или адаптировать меню под CSS-фреймворк.

Можно ли вывести одно и то же меню в нескольких местах?

Да. Одно меню можно назначить сразу в несколько областей на экране «Внешний вид → Меню», а также выводить виджетом «Произвольное меню» в разных сайдбарах и подвалах. Содержимое будет общим — изменения в админке применятся во всех местах вывода.

TimeWeb

Вывод: меню WordPress под контролем

Меню WordPress — это не магия, а понятная связка трёх уровней: данные в базе (таксономия nav_menu), области, зарегистрированные темой (register_nav_menus()), и вывод в шаблоне (wp_nav_menu()). Разобравшись с этими тремя уровнями, вы сможете:

  • создавать и редактировать меню в админке без правки кода;
  • делать многоуровневые выпадающие меню с нормальной поддержкой мобильных;
  • выводить навигацию в шапке, подвале, сайдбаре и в любом месте темы;
  • добавлять и скрывать пункты программно;
  • полностью переопределять разметку меню через walker-классы.

Начните с малого: зарегистрируйте области в functions.php, создайте меню в админке и выведите его в шапке. Затем добавьте выпадающие подменю, а программные трюки подключайте по мере необходимости — они пригодятся, когда навигация начнёт обрастать логикой (роли пользователей, каталог, языковые версии).

Если вы хотите заказать сайт на WordPress или доработку навигации под ключ — посмотрите примеры наших работ в портфолио, а больше полезных материалов ищите в блоге delai-sait.ru. Мы поможем сделать сайт, которым удобно пользоваться и который хорошо ранжируется в поиске.

Clearfy

Поделиться:
Telegram ВКонтакте