Кстати, рекомендую вам подробнейший видеоурок про меню WordPress.
Функция позволяет вывести уже созданное меню WordPress в шаблоне вашего сайта.
wp_nav_menu( $args = array() )
div
, но вы например можете указать nav
или false
, если не хотите, чтоб меню помещалось в дополнительный контейнер. По умолчанию разрешены только теги div
и nav
, но вы можете изменить это хуком wp_nav_menu_container_allowedtagsmenu-{menu slug}-container
.aria-label
, которое будет добавляться к контейнеру, если этот контейнер – тег nav
.<ul>
. По умолчанию – ярлык меню.<ul>
. По умолчанию menu
.
wp_page_menu
, выводящая страницы сайта, но вы можете указать тут название своей функции, либо false
.<a>
каждого элемента меню.</a>
каждого элемента меню.true
.1
, то все субменю будут проигнорированы, если же оставить значение параметра по умолчанию 0
, то будут выводиться все уровни вложенности.<li>
или <a>
и многое другое. Подробнее в видеоуроке.<ul id="%1$s" class="%2$s">%3$s</ul>
preserve
(по умолчанию) или discard
.Прежде всего функция wp_nav_menu()
чекает параметр theme_location
и выводит соответствующее меню, ассоциирующееся с этой областью темы. Если это области не существует или нет меню, присвоенного к этой области, то будет выполнены функция в параметре fallback_cb
.
Если же параметр theme_location
не задан вообще, тогда:
menu
.fallback_cb
(или же функция wp_page_menu()
, как значение по умолчанию).$args = array( 'theme_location' => 'truemisha_location', 'depth' => 1, 'container' => 'nav', 'fallback_cb' => false ); wp_nav_menu( $args );
Тут достаточно зарегистрировать две области theme_location
меню и использовать функцию is_user_logged_in() для переключения между ними.
$args = array( 'theme_location' => is_user_logged_in() ? 'logged-in-menu' : 'logged-out-menu' ); wp_nav_menu( $args );
Возможно вам удобнее будет использовать этот готовый сниппет, чтобы копировать его в вашу тему WordPress и уже в нём делать изменения параметров.
wp_nav_menu( array( 'menu' => '', // ID, имя или ярлык меню 'menu_class' => 'menu', // класс элемента <ul> 'menu_id' => '', // id элемента <ul> 'container' => 'div', // тег контейнера или false, если контейнер не нужен 'container_class' => '', // класс контейнера 'container_id' => '', // id контейнера 'fallback_cb' => 'wp_page_menu', // колбэк функция, если меню не существует 'before' => '', // текст (или HTML) перед <a 'after' => '', // текст после </a> 'link_before' => '', // текст перед текстом ссылки 'link_after' => '', // текст после текста ссылки 'echo' => true, // вывести или вернуть 'depth' => 0, // количество уровней вложенности 'walker' => '', // объект Walker 'theme_location' => '', // область меню 'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s</ul>', 'item_spacing' => 'preserve', ) );
Также для вашего удобства расскажу про CSS-классы, которые применяются к элементам меню (чтобы вам лишний раз не пришлось инспектировать код).
Хочу напомнить, эти классы все легко перезаписываются при помощи параметра walker
, про который я рассказывал в видеоуроке.
Все элементы меню:
.menu-item
.menu-item-has-children
.menu-item-object-{object}
{object}
– название типа поста или таксономии, либо custom
– если это произвольная ссылка..menu-item-type-{type}
post_type
или taxonomy
, или custom
..menu-item-home
Текущие элементы меню:
.current-menu-item
.current-menu-parent
.current-menu-ancestor
В функции wp_nav_menu()
есть несколько хуков, которые позволяют модифицировать вывод меню.
Если у вас нет возможности изменять параметры меню непосредственно в шаблоне (допустим вы работаете с готовой темой) и не хотите изменять файл шаблона в дочерней теме, то можете изменить любые параметры функции при помощи хука wp_nav_menu_args
, например:
add_filter( 'wp_nav_menu_args', 'true_change_nav_menu_args', 25 ); function true_change_nav_menu_args( $args ) { if( 'true_loc_1' == $args[ 'theme_location' ] ) { $args[ 'depth' ] = 1; // например отключим сабменю в локации true_loc_1 } return $args; }
Позволяет перезаписать HTML меню целиком ещё перед тем, как оно будет сгенерировано.
add_filter( 'pre_wp_nav_menu', 'true_change_completely', 25, 2 ); function true_change_completely( $nav_menu, $args ) { // например меню в локации true_loc_2 не отображаем для незарегистрированных if( 'true_loc_2' == $args[ 'theme_location' ] && ! is_user_logged_in() ) { return 'Это меню доступно только для зарегистрированных, ребята!'; } return null; }
Позволяет задать разрешённые теги в контейнере меню. По умолчанию это только div
или nav
. Но вы можете добавить сюда и другие теги, либо наоборот, запретить уже разрешённые.
Запрещаем тег nav
:
add_filter( 'wp_nav_menu_container_allowedtags', 'true_no_nav_tag', 25 ); function true_no_nav_tag( $allowed_tags ) { return array( 'div' ); }
Если указан любой неразрешённый HTML-тег, то контейнер добавлен не будет.
Этот хук позволяет нам пройтись по всем элементам меню перед их выводом и сделать в них какие-либо изменения.
Например мы можем добавить какой-то произвольный CSS-класс к текущему элементу меню:
add_filter( 'wp_nav_menu_objects', 'true_add_css_class_to_current' ); function true_add_css_class_to_current( $items ) { // вы всегда можете распечатать массив объектов меню // print_r( $items ); foreach ( $items as $item ) { // или конкретный объект меню // print_r( $item ); if ( $item->current ) { // если это текущий элемент, то добавляем ещё класс $item->classes[] = 'current'; } } return $items; // возвращаем изменённый массив объектов }
Позволяет отфильтровать HTML элементов меню без контейнера и тега <ul>
.
add_filter( 'wp_nav_menu_items', 'true_new_menu_html', 25, 2 ); function true_new_menu_html( $items, $args ) { // делаем какие-то изменения в $items // например для меню в локации header_menu можем добавить ссылку на инстаграм if ( 'header_menu' == $args->theme_location ) { $items .= '<li><a href=""><i class="icon-instagram"></i></a></li>'; } return $items; }
У этого фильтра также есть и частный случай – wp_nav_menu_{ярлык меню}_items
.
Практически аналогичен предыдущему фильтру, отличие в том, что тут мы фильтруем целиком готовый HTML код меню, уже с контейнером и тегом <ul>
.
Мой видеокурс по натяжке готового дизайна и HTML-вёрстки на WordPress.
Чтобы оставить комментарий, пожалуйста, зарегистрируйтесь или войдите.
Спасибо за Вашу работу! Помогли! Дай Бог Вам здоровья и успехов!
Спасибо)
Все вроде получилось, но есть одно НО)
(установил плагин UberMenu). Хочу добавить это меню в сайдбар.
Сделал все как у вас.
Когда выбираю области темы, которые уже были в самой теме, то плагин работает.
А в созданной мной - нет. Не подскажете, что может быть?
посмотри, может зависит от css класса меню
Спасибо! Посмотрю!
А как стилизовать, чтобы меню стояло в один ряд? Без этого меню появляется, как рубрики в сайт-баре.
Добрый день,
можно использовать следующие CSS-стили к соответствующим элементам меню:
или
Доброй ночи, Михаил.
Надеюсь на Вашу помощь, сама зашла в тупик.
Пытаюсь написать walker, который группирует пункты меню по 2
Чтобы визуально разделить на две колонки.
Попробовала так
И вроде нормально, но если я поменяю местами пункты в уже созданном меню, то всё съезжает..
Пробовала прикрутить обработчик из кодекса, но у меня он упорно ставить even ВСЕМ элементам li верхнего уровня. А odd только если depth меняю - создаю подменю, вот у него odd-класс.
Подскажите, как сделать чет-нечет?
Нда...
Всё оказалось проще некуда..
заменила
на
Миш, а можно еще немного помощи попросить =)?
Сейчас у меня такая таксономия
произвольная ссылка (href="#")>> рубрика >> ее подрубрика >> запись
И когда я на странице записи — произвольной ссылке НЕ присваивается класс current .
Прочла, что произ.ссылки хранятся в БД отдельно...
По логике тогда в валкере нужно сделать проверку, чтобы на странице записи присваивать current класс самому высшему родительскому пункту меню, если такой класс есть у дочернего.
Но что-то уже весь рунет и буржунет облазила, а решения не нашла.
оу, боюсь, что с ходу я тут не скажу,
нужно смотреть и разбираться..
Это не критично, но мой перфекционизм не дает спать =). Если вдруг встретишь решение или осенит - маякни, пожалуйста.
окей, не вопрос)
Уважаемый, хоть я и оставлял комментарий здесь, но не помню, чтобы подписывался на новые комментарии к данной статье. Возможно, я просто не заметил галочку, которая стоит по умолчанию. Прошу Вас отписать от получения уведомлений о новых комментариях. Если уж сделали фичу на подписку, резонно было бы дать людям самостоятельно отписаться.
Отписал вас.
Да, согласен, всё никак не успеваю доработать это.
Добрый день, Миша.
Не подскажешь как добавить номер в классы пунктов верхнего уровня меню?
Чтобы было так
menu_order нумерует по порядку без привязки к depth
Добрый день!
я бы залез в файл, где определяется функция и поискал бы там фильтры для классов, ну и скорее всего через волкер можно реализовать.
Через волкер и пытаюсь =)..
но стандартно $i=0 if (depth=0) $i++ не получается прикрутить.
а почему?
Думаю тут в волкере поможет параметр
$item->menu_item_parent
. То есть, если этот параметр не существует, то делаем инкремент счетчика.P.S. Скажу честно, когда ты меня три месяца назад спросила про это, я в волкерах был полным нубом :)
Да я сама методом тыка всё осваиваю =)..
Я уже там что-то другое навертела, но на будущее запомню), спасибо!
Если я в start_el дописываю в скобки $i=0, потом пишу $i++ и условие, то соответственно li каждый раз обнуляется и у всех class="li-1". А если не писать эту переменную или не присваивать ей нулевое значение, то счетчик вообще не работает.
Или я что-то напутала?
Михаил, доброго времени суток. У меня такая трабла:
Клиент требует убирать из меню те страницы сайта (меню основано на страницах), для которых стоит статус "Черновик" или "На утверждении".
Можно ли каким нибудь способом, либо:
a) не формировать это меню в момент сборки, или же
б) присваивать такому пункту какой либо, скажем, класс, например class="hiddenitem"
В данный момент меню формируется следующим образом:
Спасибо!
Я не Миша =), но может Вам подключить валкер и в нем прописать что-то вроде
Здравствуйте!
Создал 2х уровневое меню в админке.
Пытаюсь создать новую тему.
Вывожу меню так:
Почему то вместо такого результата:
Получаю такой:
Почему не получаю ожидаемого результата? Есть какие-то тонкости использования функции wp_nav_menu?
Здравствуйте! Попробуйте:
Как через get_the_post_thumbnail() прикрепить миниатюры в навигационное меню. не могу сообразить.
Я бы начал с этой функции wp_get_nav_menu_items().
а можно ли внутрь тега <a> запихнуть тег с атрибутом title?
Ну через волкер все возможно.
Как прописать атрибут title к ссылкам в меню Рубрики на сайте http://espana-live.com/? В каком файле внести изменения? nav-menu.php или nav-menu-template.php?
Михаил, добрый день! Помню как-то вы мне помогли в одном вопросе, за это спасибо! Может поможете и в этом?
Суть в следующем: есть плагин WP-Recall, там есть личный кабинет в котором выводятся кнопки, делаю тему для WordPress и хотел бы сделать меню, что бы эти кнопки отображались в меню темы. а не на странице плагина!
Разработчик написал, что это возможно, написал следующее:
"Добрый день, да, это вполне возможно, все действующие вкладки личного кабинета можно получить в глобальной переменной $rcl_option['tabs'], затем обратиться к массиву данных нужного меню сайта и добавить туда нужные пункты используя данные из $rcl_option['tabs'], в результате меню выведет добавленные кнопки.
Чтобы получить объекты нужного меню вроде можно использовать фильтр wp_nav_menu_objects, там два аргумента $sorted_menu_items и $args, в первом находятся сформированные объекты пунктов меню, а во втором настройки переданные через функцию wp nav menu."
Вот подскажите, как получить глобальную переменную $rcl_option['tabs'], я не пойму...
Добрый день!
Возможно я мог бы подсазать вам точнее, если бы сам пользовался плагином WP-Recall, а вообще к глобальной переменной обратиться легко:
И что мне потом делать с $tabs ?
Вопрос был, как получить глобальную переменную
$rcl_option['tabs']
и я ответил.Я так полагаю, после этого у вас имеется массив элементов — тут уже можете делать что угодно, либо просто дописать в файлах темы, либо, как вам ответил супорт, использовать фильтр
wp_nav_menu_objects
, либо функцию из меню. На самом деле ничего сложного, главное понимать в общих чертах, как работают массивы PHP.На странице меню выводится так
Подскажите пожалуйста как можно туда вставить микроразметку
itemscope itemprop="http://schema.org/SiteNavigationElement"
Я думаю в этой статье вы найдёте ответ.
Добрый день! Подскажите как сделать динамически смену области меню при переходе на другую страницу.
Добрый день!
При переходе с какой и на какую страницу?
Привет Миша! Как сделать так чтобы при активации темы чекбокс "Automatically add new top-level pages to this menu" Автоматически был установлен? Идея такова что при активации темы у человека будет сразу создана главная с меню (страницы тоже создаются автоматически).
P.S Спасибо за кладезь знаний в виде этого сайта.
Привет!
Готовый код не подскажу, но могу подсказать алгоритм.
Сами менюхи являются элементами таксономии
nav_menu
, а настройка автоматического добавления находится в опциях сайта, вnav_menu_options
.Теоретически мы можем использовать хук
create_{$taxonomy}
, то естьcreate_nav_menu
и при создании автоматически сохранять нужную опцию. Но я не тестировал, это всё теоретически :)