WordPress. Меню навигации. Часть 1 из 2
25.03.2019
Теги: CMS • Web-разработка • 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