Удобный и Быстрый Хостинг для сайтов на WordPress. Пользуюсь сам и вам рекомендую!

Произвольное меню в WP 3.0+ (wp_nav_menu)

Широко известно, что в WordPress 3.0 добавлена поддержка произвольных меню (настраиваемых меню). Вещь, на мой взгляд, крайне удобная и полезная. Собственно, отсюда и эта статья.

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

Однако, чтобы такая "свобода" была доступна, нужно, скажем так, легким движением мышки, настроить вывод произвольного меню в шаблон.

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

Работает через таксономию nav_menu, а произвольные (внешние) ссылки, записываются в таблицу wp_posts. Такой подход более гибкий и динамичный, однако требует постоянной генерации таких меню.

Итак, приступим.

Видео по меню в WordPress

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

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

register_nav_menus( [
	'top'    => 'Верхнее меню', // Название слота для меню в шаблоне
	'bottom' => 'Нижнее меню'   // Название другого слота меню в шаблоне
] );

Мы зарегистрировали 2 слота для меню с идентификаторами top и bottom с соответствующими им названиями. Идентификаторы нужны, чтобы использовать их в теме, в параметрах функции wp_nav_menu(), которая будет выводить созданное в админке меню. Названия зарегистрированных слотов мы увидим в админке, когда зайдем в раздел Внешний вид -> Меню.

Зарегистрированные места расположений меню

После того, как слоты зарегистрированы, идем в админку и создаем свои меню (в данном примере 2 менюшки):

  1. Задаем название меню. Меню в шаблоне можно выводить по указанному названию, функцией wp_nav_menu( [ 'menu'=>'Name' ] )

  2. Добавляем элементы в меню. Используем левый блок: страницы ссылки, рубрики.

  3. Выбираем слот для меню (где будет расположено), так как мы зарегистрировали 2 слота, у нас будет 2 варианта: "Верхнее меню" и "Нижнее меню".

Создание произвольного меню в WordPress. Админ-панель.

Поддержка меню в WP включается отдельно для темы, функцией add_theme_support('menus'). Однако, при регистрации слотов нет необходимости включать поддержку отдельно - это делается автоматически.

Вывод произвольных меню через функцию wp_nav_menu()

Важно: нюанс с отсутствующим меню

При использовании функции wp_nav_menu(), если указанный theme_location не существует или не назначено ни одно меню, WordPress автоматически переключается на wp_page_menu(), которая выводит список всех страниц. При этом параметры container, container_class и прочие начинают применяться к <ul>, а не к контейнеру, это может нарушить ожидаемую HTML-разметку.

Пример:

$menu = wp_nav_menu( [
	'theme_location'  => 'my_location',

	'container'       => 'nav',
	'container_class' => 'nav header__nav',
	'menu_class'      => 'header__list',
	'menu_id'         => 'my-id',

	'echo' => false,
] );

echo htmlspecialchars( $menu );

Результат, когда нет "my_location" или в нем нет ни одного меню:

<nav id="my-id" class="header__list">
	<ul>
		<li class="page_item page-item-14813"><a href="УРЛ">Заголовок страницы</a></li>
	</ul>
</nav>

Результат, когда в "my_location" есть меню:

<nav class="nav header__nav">
	<ul id="my-id" class="header__list">
		<li id="menu-item-6411" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-6411">
			<a href="УРЛ">Заголовок элемента меню</a>
		</li>
	</ul>
</nav>

Подробнее читайте в комментарии.

Теперь, осталось вывести меню в шаблоне. Делается это функцией wp_nav_menu(), которая может принимать следующие параметры:

wp_nav_menu( array(
	'menu'            => '',              // (string) Название выводимого меню (указывается в админке при создании меню, приоритетнее
										  // чем указанное местоположение theme_location - если указано, то параметр theme_location игнорируется)
	'container'       => 'div',           // (string) Контейнер меню. Обворачиватель ul. Указывается тег контейнера (по умолчанию в тег div)
	'container_class' => '',              // (string) class контейнера (div тега)
	'container_id'    => '',              // (string) id контейнера (div тега)
	'menu_class'      => 'menu',          // (string) class самого меню (ul тега)
	'menu_id'         => '',              // (string) id самого меню (ul тега)
	'echo'            => true,            // (boolean) Выводить на экран или возвращать для обработки
	'fallback_cb'     => 'wp_page_menu',  // (string) Используемая (резервная) функция, если меню не существует (не удалось получить)
	'before'          => '',              // (string) Текст перед <a> каждой ссылки
	'after'           => '',              // (string) Текст после </a> каждой ссылки
	'link_before'     => '',              // (string) Текст перед анкором (текстом) ссылки
	'link_after'      => '',              // (string) Текст после анкора (текста) ссылки
	'depth'           => 0,               // (integer) Глубина вложенности (0 - неограничена, 2 - двухуровневое меню)
	'walker'          => '',              // (object) Класс собирающий меню. Default: new Walker_Nav_Menu
	'theme_location'  => ''               // (string) Расположение меню в шаблоне. (указывается ключ которым было зарегистрировано меню в функции register_nav_menus)
) );

В данном примере в шаблон нужно вставить примерно (зависит от необходимых вам параметров) такие, 2 кода:

#1. Вывод меню по расположению

Верхнее меню. Вставляем в шапку шаблона (header.php), там где будет выводится верхнее (top) меню:

<?php
wp_nav_menu( array(
	'menu_class'=>'menu',
	'theme_location'=>'top',
	'after'=>' /'
) );
?>

Выведет созданное в админке меню, прикрепленное к расположению "Верхнее меню" с подобной структурой:

<div class='<классы WP>'>
	<ul class='menu'>
		<li><a class='<классы WP>' href="#">Анкор ссылки</a> /</li>
		<li><a class='<классы WP>' href="#">Анкор ссылки</a> /</li>
		<li><a class='<классы WP>' href="#">Анкор ссылки</a> /</li>
	</ul>
</div>

Нижнее меню. Вставляем в подвал шаблона (footer.php), там где будет выводится нижнее (bottom) меню:

<?php wp_nav_menu('menu_class=bmenu&theme_location=bottom'); ?>

Выведет созданное в админке меню, прикрепленное к расположению "Нижнее меню". Структура будет идентичная первой.

Обратите внимание, в первом варианте параметры были переданы через массив (array). Во втором через строку. Оба варианта правильны. Это обычное дело для функций WordPress - параметры можно передавать как массивом, так и строкой (строка потом преобразовывается в массив).

#2 Выводим меню по названию

Чтобы вывести меню по его названию можно воспользоваться аргументом 'menu'. Название указывается, то которое было задано при создании меню в админке. В нашем примере (см. картинку) "Главное меню". Аргумент menu обладает большим приоритетом чемtheme_location, а значит, если мы выводим по названию, то параметр theme_location будет игнорироваться.

<?php wp_nav_menu('menu=Главное меню'); ?>

Можно указать ID меню, а не название. Так, при изменении названия меню, код останется рабочим. ID меню можно посмотреть в УРЛ во время редактирования меню:

<?php wp_nav_menu('menu=455'); ?>

Заметки

Уберем обертку Div

Вы наверное обратили внимание, что меню "оборачивается", часто, ненужным тегом div. Его можно удалить, указав в аргументах для функции wp_nav_menu() пустой параметр 'container'=>''.

Изменяем параметры по умолчанию

Чтобы постоянно не указывать один и те же параметр для вставляемых меню, их можно переопределить в functions.php. Делается это через фильтр wp_nav_menu_args:

register_nav_menus( [
	'top'    => 'Верхнее меню',
	'bottom' => 'Нижнее меню'
] );

add_filter( 'wp_nav_menu_args', 'my_wp_nav_menu_args' );
function my_wp_nav_menu_args( $args='' ){
	$args['container'] = '';
	return $args;
}

По аналогии, можно создать свои аргументы по умолчанию: $args['аргумент'] = 'значение'.

Проверка зарегистрировано ли меню

В WordPress так же есть, функция условия: has_nav_menu('top') - проверяет было ли зарегистрировано расположение меню top. Если меню не указано, то функция wp_nav_menu() сработает, как wp_list_pages(), но "обворачиватель" div останется, несмотря на то что в аргументах мы его убрали. Решить эту проблему можно так:

if( has_nav_menu('top') ){
	wp_nav_menu( [
		'container' => '',
		'theme_location' => 'top',
		'menu_class' => 'menu'
	] );
}
else {
	echo '<ul class="menu">';
	wp_list_pages( array('depth' => 1, 'title_li' => '' ));
	echo '</ul>';
}

Параметр walker

Из всех передаваемых аргументов, непонятным является walker. Для тех, кто хочет разобраться для чего он нужен, читайте раздел в описании функции wp_nav_menu(). Там коротко и ясно описан принцип. Если очень коротко, то с его помощью можно внедриться в процесс генерации меню и изменить его как угодно.

Включение доп. параметров у меню

Меню можно настроить, например, можно добавить возможность указывать CSS класс для элемента меню, для ссылки меню. Для этого откройте вкладку «Настройки экрана»:

72 комментария
Полезные - 5Вопросы - 1 Все