wp_nav_menu() – вывод меню

Кстати, рекомендую вам подробнейший видеоурок про меню WordPress.

Функция позволяет вывести уже созданное меню WordPress в шаблоне вашего сайта.

wp_nav_menu( $args = array() )

Параметры

$args
(массив) параметры функции
menu
(строка) В этом параметре можно указать ID, ярлык или название меню, которое вы хотите отобразить на сайте.
theme_location
(строка) Область темы, меню, добавленное в которую, нужно отобразить. Подробнее про области темы в видеоуроке.
container
(строка) HTML-тег, в которое будет обрамляться меню, по умолчанию div, но вы например можете указать nav или false, если не хотите, чтоб меню помещалось в дополнительный контейнер. По умолчанию разрешены только теги div и nav, но вы можете изменить это хуком wp_nav_menu_container_allowedtags
container_class
(строка) CSS-класс элемента контейнера. По умолчанию menu-{menu slug}-container.
container_id
(строка) Атрибут id контейнера.
container_aria_label
(строка) Значение атрибута aria-label, которое будет добавляться к контейнеру, если этот контейнер – тег nav.
menu_id
(строка) Атрибут id самого меню, элемента <ul>. По умолчанию – ярлык меню.
menu_class
(строка) CSS-класс самого меню, элемента <ul>. По умолчанию menu.
fallback_cb
(строка) В том случае, если указанное меню не существует, то указанная здесь функция будет выполняться, по умолчанию это wp_page_menu, выводящая страницы сайта, но вы можете указать тут название своей функции, либо false.
before
(строка) Текст или HTML перед ссылкой <a> каждого элемента меню.
after
(строка) Текст или HTML после ссылки </a> каждого элемента меню.
link_before
(строка) Текст или HTML перед текстом ссылки каждого элемента меню.
link_after
(строка) Текст или HTML после текста ссылки каждого элемента меню.
echo
(логическое) Вывести или вернуть меню? По умолчанию меню выводится, параметр равен true.
depth
(целое число) Укажите уровень вложенности, который будет поддерживаться этим меню. Например, если указать 1, то все субменю будут проигнорированы, если же оставить значение параметра по умолчанию 0, то будут выводиться все уровни вложенности.
walker
(объект) Этот параметр позволяет указать объект класса Walker-класса для меню, который позволит вам настроить довольно серьёзные кастомизации, например вывести элементы меню по бутстрапу, изменить ID и классы любого тега внутри меню, будь то <li> или <a> и многое другое. Подробнее в видеоуроке.
items_wrap
(строка) HTML-шаблон элементов меню, по умолчанию <ul id="%1$s" class="%2$s">%3$s</ul>
item_spacing
(строка) Нужно ли оставлять строк в HTML коде меню. Может принимать значения: preserve (по умолчанию) или discard.

Как это работает?

Прежде всего функция wp_nav_menu() чекает параметр theme_location и выводит соответствующее меню, ассоциирующееся с этой областью темы. Если это области не существует или нет меню, присвоенного к этой области, то будет выполнены функция в параметре fallback_cb.

Если же параметр theme_location не задан вообще, тогда:

  1. Сначала функция попробует вывести меню по ID, ярлыку или имени, указанному в параметре menu.
  2. Иначе – первое непустое меню, созданное в админке.
  3. Иначе – выполнится функция в параметре fallback_cb (или же функция wp_page_menu(), как значение по умолчанию).
  4. Иначе – ничего.

Примеры

Меню без уровней вложенности с контейнером <nav>

$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-классы элементов меню

Также для вашего удобства расскажу про CSS-классы, которые применяются к элементам меню (чтобы вам лишний раз не пришлось инспектировать код).

Хочу напомнить, эти классы все легко перезаписываются при помощи параметра walker, про который я рассказывал в видеоуроке.

Все элементы меню:

  • .menu-item
    Добавляется к каждому элементу меню.
  • .menu-item-has-children
    Добавляется к каждому элементу меню, у которого есть дочерние элементы .
  • .menu-item-object-{object}
    Будет добавлен к элементам меню, представляющим тип записи или таксономию, где {object} – название типа поста или таксономии, либо custom – если это произвольная ссылка.
  • .menu-item-type-{type}
    Добаляется к каждому элементу меню, {type} может принимать одно из трёх значений: post_type или taxonomy, или custom.
  • .menu-item-home
    Добавляется к элементу меню, ведущему на главную страницу сайта.

Текущие элементы меню:

  • .current-menu-item
    Будет добавлен к текущему элементу меню (то есть на странице которого мы находимся).
  • .current-menu-parent
    Если текущий элемент меню является дочерним, то к его родительскому элементу будет добавлен этот класс.
  • .current-menu-ancestor
    Если текущий элемент меню является дочерним, то к его прямому родительскому элементу будет добавлен этот класс.

Экшены и фильтры функции wp_nav_menu()

В функции 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;
}

pre_wp_nav_menu

Позволяет перезаписать 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.

Миша

Впервые познакомился с WordPress в 2009 году. Организатор и спикер на конференциях WordCamp. Преподаватель в школе Нетология.

Пишите, если нужна помощь с сайтом или разработка с нуля.

Комментарии — 41

Чтобы оставить комментарий, пожалуйста, зарегистрируйтесь или войдите.

Миша Рудрастых и WordPress

Полезности из мира WordPress и жизни студии.

Мой телеграм-канал