- Создать тестовый сайт на локальном сервере. Я делаю на OpenServer. Для этого создам папку testmenu в директории OpenServer/domains/ и скопирую туда файлы из папки wordpress. Создать новую базу и пользователя в PhpMyAdmin. И активирую сайт testmenu
- Создать тестовую тему в папке wp-content/themes/. Назову ее также: testmenu.


3. Открою папку с темой в Visual Studio Code.
4. Создать минимальный набор файлов для активации тестовой темы: index.php и style.css
5. Пропишу в файле style.css следующий код:
/* Theme Name: myTheme22 Version: 1.0 Description: Моя тема с нуля Author: Debugger Author URI: https://debuggerplus.com */
Главное, чтобы присутствовал параметр Theme Name. Тогда ваша тема появится в списке тем в админке сайта и ее можно будет активировать.

6. Для наглядности добавим превью темы. Для этого добавим в тему заранее подготовленное изображение с названием screenshot.png

В админке сайта нет возможности создания меню.

8. Исправим это. Для этого надо создать файл functions.php. И прописать в него следующий код:
<?php add_action('after_setup_theme', function(){ add_theme_support('menus'); }) ?>
В админке сайта добавится возможность добавления меню.

9. Добавим произвольное меню. Создадим несколько тестовых страниц и добавим их меню и нажмем «Сохранить меню»

Если обновить страницу сайта, то меню нигде не отобразится.
10. Запишем в файле index.php следующий код:
<?php wp_nav_menu(); ?>
Тогда при обновлении страницы, мы увидим наше меню.

Функция wp_nav_menu() без параметров выводит последнее созданное непустое меню. Если такого меню не находит, то сама создает меню из постоянных страниц.
Параметры функции wp_nav_menu()
Ниже показаны параметры по умалчанию.

menu
Параметр menu указывает, какое меню выводить. В параметре меню указывается id, slag или название необходимого меню.
<?php wp_nav_menu ([ 'menu' => 'main-menu' ]); ?>
theme_location — содержит локацию области меню.
Чтобы использовать этот параметр, сначала надо в файле functions.php зарегистрировать область меню функцией register_nav_menu(‘локация меню’,’Название меню’);
Пример кода:
<?php add_action('after_setup_theme', function(){ add_theme_support('menus'); register_nav_menu('header-menu','Верхняя область'); }) ?>
В админке сайта появится область отображения меню.

Добавим еще одну область отображения.
<?php add_action('after_setup_theme', function(){ add_theme_support('menus'); register_nav_menu('header-menu','Верхняя область'); register_nav_menu('footer-menu', 'Нижняя область'); }) ?>

Функция register_nav_menu(); регистрирует только одну область за раз.
Если нужно зарегистрировать сразу несколько областей, то можно воспользоваться функцией register_nav_menus();
register_nav_menus([ 'header-menu' => 'Верхняя область', 'footer-menu' => 'Нижняя область', 'sidebar-menu' => 'Боковое меню' ]);

При изсользвании функции register_nav_menus(); не надо прописывать функцию активации поддержки произвольных меню add_theme_support(‘menus’); функция делает это сама.
has_nav_menu()
Функция has_nav_menu() проверяет наличие меню в указанной области.
if(has_nav_menu('header-menu')){ // Что-то перед меню wp_nav_menu([ 'theme_location' => 'header-menu', ]); // Что-то после меню } else { }
Если меню существует, то оно выводится в соответствующей области, если нет, то выполняется инструкция else.
fallback_cb
То же самое можно сделать с помощью фунции fallback_cb.
$menu=wp_nav_menu([ 'theme_location' => 'footer-menu', 'fallback_cb' => null, 'echo' => false ]); if($menu) { // Что-то, если надо echo $menu; // Что-то, если надо } else { // Выводим что-то вместо заглушки }
echo
Параметр ‘echo’ => false используется для того, чтобы получить html-код меню. Вставить в нужное место нужные классы и вывести на экран.
if(has_nav_menu('header-menu')){ $menu = wp_nav_menu([ 'theme_location' => 'header-menu', 'echo' => false ]); $menu = str_replace('menu-item', 'my__class',$menu); echo $menu; // Или делаем return, если ситуация требует }
fallback_cb
function show_when_menu_is_empty() { echo 'Создайте меню, иначе без него внешний вид сайта портится.'; } wp_nav_menu([ 'theme_location' => 'header-menu1111', 'fallback_cb' => 'show_when_menu_is_empty' ]);
Если меню не существует, то выполнится функция, которая выводит на экран сообщение.

walker
В параметр walker нужно передавать объект класса, который будет использоваться для построения меню.
wp_nav_menu([ 'theme_location' => 'header-menu', 'walker' => new My_Menu_Walker() ]);
container
Параметр container определяет, чем будет обернут тег ul. По умолчанию div. Можно указать nav. Если не нужно ничем оборачивать, то укзываем false.
container_id
Параметр container_id определяет html-атрибут id у контейнера. По умолчанию: пустая строка.
container_class
Параметр container_class определяет html-атрибут class у контейнера.
menu_id
Этот параметры определяет значение html-атрибута id у тега ul. По умолчанию, пустая строка.
menu_class
Определяет значение class тега ul. По умолчанию: menu.
before
Выводит произвольный текст или html-код перед тегом a.
after
После тега а.
link_before
Тоже самое перед анкором. Часто используется для вставки иконок.
link_after
Тоже самое после анкора ссылки.
items_wrap
Указывает, нужно ли оборачивать элемент в тег ul. Если нужно, указывается шаблон обертки. По умолчанию ‘<ul id=»%1$s» class=»%2$s»>%3$s</ul>’.
depth
Количество уровней вложенности. По умолчанию 0, все уровни выводятся. 1 — все пункты первого уровня.
item_spacing
Определяет, оставлять или нет переносы строк в html-коде меню. Это можно увидеть в исходном коде html-страницы. По умолчанию preserve — оставлять. Discard — не оставлять.
wp_nav_menu([ 'theme_location' => 'header-menu', 'container' => 'nav', 'container_id' => 'id__container', 'container_class' => 'class__container', 'menu_id' => 'id_menu', 'menu_class' => 'class__menu', 'before' => 'До ссылки', 'link_before' => 'До анкора', 'link_after' => 'После анкора', 'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s</ul>', 'depth' => 1, 'item_spacing' => 'discard' ]);