Коротко о главном
Уже широко известно, что в WordPress 3.0 добавлена поддержка произвольных меню (настраиваемых меню). Вещь, на мой взгляд, крайне удобная и полезная. Собственно, отсюда и эта статья.
Удобство заключается в том, что теперь можно создавать и конфигурировать менюшки прямо из админки, добавляя ссылки кликами по чекбоксам и меняя порядок ссылок простым их перетаскиванием. В меню можно добавить ссылки на страницы, категории и отдельные посты. Можно создавать многоуровневые меню, так же в меню можно добавлять свои ссылки (обычно внешние) - ссылки о которых WordPress не знает. В общем, полная свобода действий.
Однако, чтобы такая "свобода" была доступна, нужно настроить вывод произвольного меню в шаблон, чтобы потом управлять им из админки, так скажем, легким движением мышки 
Использовать такие меню будет крайне удобно, если пользоваться мультисайтовой возможностью WordPress, потому что для разных сайтов можно будет настраивать разные меню, а шаблон для них использовать один.
Огорчает, то что меню работает через таксономию (nav_menu) WordPress, а произвольные (внешние) ссылки, записываются в основную таблицу БД posts. Такой подход более гибкий и динамичный, однако требует постоянной генерации таких меню, поэтому такие меню создают довольно приличную нагрузку, если учитывать что это всего-лишь меню. Использовать такие меню без каких-либо плагинов кеширования я бы не рекомендовал.
Такая уж концепция у разработчиков WordPress - удобство превыше всего, несмотря на то, что порой оно не оправдано производительностью.
Итак, приступим.
Включаем поддержку произвольных меню (wp_nav_menu)
Для начала нужно зарегистрировать возможность использования произвольных меню и сами меню. Делается это в файле functions.php, так:
register_nav_menus(array(
'top' => 'Верхнее меню', //Название месторасположения меню в шаблоне
'bottom' => 'Нижнее меню' //Название другого месторасположения меню в шаблоне
));
Сейчас мы зарегистрировали 2 меню с идентификаторами 'top' и 'bottom', с соответствующими им названиями (можно кириллицой). Идентификаторы нужны будут, чтобы обращаться к определенному меню через функцию вывода wp_nav_menu. Названия месторасположений мы увидим в админке, когда зайдем в раздел редактирования произвольных меню (Внешний вид -> Меню). Там же мы будем привязывать какое, созданное нами, меню где должно располагаться.
После того, как меню зарегистрированы, идем в админку и создаем свои меню (в данном примере 2 менюшки): даем им названия (функция wp_nav_menu может выводить по этому названию), слева, выбираем где будет расположено меню, так как мы зарегистрировали 2 менюшки "top", "bottom", у нас будет 2 варианта: "Верхнее меню" и "Нижнее меню". Слева ниже добавляем ссылки.
add_theme_support('menus'); Однако, в этой строчке нет необходимости, если мы сразу зарегистрируем меню. В этом случаем поддержка будет включена автоматически.Вывод произвольных меню через функцию wp_nav_menu
Меню зарегистрированы и созданы, осталось их интегрировать в шаблон. Делается это функцией wp_nav_menu(), которая может принимать следующие параметры (аргументы):
$args = 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 Array(
'menu_class'=>'menu',
'theme_location'=>'top',
'after'=>' /'
);
wp_nav_menu($args);
?>
Выведет созданное в админке меню, прикрепленное к расположению "Верхнее меню" с такой структурой:
<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>
2. Вставляем в подвал шаблона (footer.php), там где будет выводится нижнее (bottom) меню:
<?php wp_nav_menu('menu_class=bmenu&theme_location=bottom'); ?>
Выведет созданное в админке меню, прикрепленное к расположению "Нижнее меню". Структура будет идентичная первой.
Выводим меню по названию
Чтобы вывести меню по его названию можно воспользоваться аргументом 'menu'. Название нужно указывать, то под которым создавалось меню в админке. Пример:
<?php wp_nav_menu('menu=Название меню'); ?>
Тонкости
Вы наверное обратили внимание, что меню "оборачивается", часто, ненужным тегом div. Его можно удалить, указав в аргументах для функции wp_nav_menu пустой параметр 'container'=>''. Или, чтобы постоянно не обнулять этот аргумент, можно переопределить аргументы по умолчанию при регистрации меню в functions.php, делается это через фильтр wp_nav_menu_args, так:
register_nav_menus(array(
'top' => 'Верхнее меню'
,'bottom' => 'Нижнее меню'
));
function my_wp_nav_menu_args($args=''){
$args['container'] = '';
return $args;
} // function
add_filter( 'wp_nav_menu_args', 'my_wp_nav_menu_args' );
добавляя в функцию my_wp_nav_menu_args строки $args['аргумент']='значение', можно создать свои аргументы по умолчанию.
В WordPress так же есть, функция условия: has_nav_menu('primary'); - проверяет было ли указано меню для расположения primary. Если меню не указано, то функция wp_nav_menu() сработает, как wp_list_pages(), но "обворачиватель" div останется, несмотря на то что в аргументах мы его убрали. Решить эту проблему можно так:
if (has_nav_menu('top')){
wp_nav_menu( array(
'container' => '',
'theme_location' => 'top',
'menu_class' => 'menu')
);
} else {
echo '<ul class="menu">';
wp_list_pages( array('depth' => 1, 'title_li' => '' ));
echo '</ul>';
}
Из всех передаваемых аргументов, непонятным является walker. Для тех, кто хочет разобраться для чего он нужен и с чем его едят, советую прогуляться до этой статьи (знания php обязательны). Там коротко и ясно описан принцип. От себя коротко скажу, что с его помощью можно внедрится в процесс генерации меню и изменить его как угодно, правда для этого понадобятся знания в PHP.
- Предыдущие по меткам
- Предыдущие записи
- Что такое цикл the loop в WordPress ← 20.Июл.2010 // 15
- Файл шаблона functions.php в WordPress ← 6.Окт.2010 // 21
- Плагин для легкого управления сайтом на WordPress (версия 3) ← 30 Июль 2010 // 76
- Обзор WordPress 3.0. Что несет нам прогресс? ← 30 Июль 2010 // 4
- Что такое цикл the loop в WordPress ← 20 Июль 2010 // 15

Здравствуйте, а как собственно вывести для страниц меню... В меню вкладываю Страницы, а отображаются, рубрики....
Вы что-то не так делаете.
Разобрался,почему то 2 строчки брались с другого меню...

Спасибо за статью.
Правда она мне толком не помогла.
Т.к не разобрался со всеми остальными нужностями
Очень полезная статья.
Вот только что-то у меня иерархия не поддерживается. Все подСтрочк меню идут в одну линию с остальными.
И в класс ul не вставляется именно тот который я прописал. И контейнеры из дивов не убираются.
Здравствуйте.
А как сделать подсвечивание пункта главной рубрики меню, если мы находимся в записи дочерней рубрики. при этом дочерняя рубрика есть в меню также.
Использую стили для подсвечивания .current-menu-item, .current-post-parent, .current-menu-parent
Но пункт главной рубрики, когда находимся в посте подрубрики не подсвечивается
А как сделать так! Например у меня есть страница на которой нужно сделать меню, но оно должно относиться только к этой странице и не отображаться на других страницах сайта!Не пойму никак как это сделать! Может подскажите? Спасибо!
Условные теги WordPRess посмотрите... is_page()
А как сделать что бы рубрики выводились блогом на разл страницах
Спасибо, помогло на 2ух шаблонах, а то я всегда темы подбирал чтоб эта функция уже была
А тут старый шаблон очень редкий приглянулся, а без меню вообще никак, т.к. у wp и так все плохо с этим. Теперь буду мучатся с jQuery, скачал плагин интересный а внедрить не получаеться(((
Алоха!
Вопрос на засыпку! Есть меню, есть пункт первого уровня и у него подпункты второго уровня. Как сделать так, чтобы подпункты второго уровня становились видными в меню только после перехода на их родительский пункт первого уровня?
То есть перешел в раздел и раскрылся список его подразделов, а не так, чтобы он постоянно был виден изначально.
Самое простое что приходит в голову воспользоваться несколькими меню и плагином Dynamic Widgets
Огромное спасибо, менял свой дизайн и всё никак не мог разобраться меню теперь будет всё супер
Может кто знает как средствами WP заменить класс menu-item li элемента принадлежащему submenu
что бы получилось примерно такого вида
сейчас генерация меню такая
Можно сделать точно по аналогии с этим моим ответом.
напишу точнее, допустим имеем основное меню и сабменю
<ul class="menu"> <li class="menu-item menu-item-1"></li> <ul class="sub-menu"> <li class="menu-item menu-item-2"></li> <li class="menu-item menu-item-3"></li> </ul> </ul>применив функцию из ответа
$cat_list = wp_nav_menu('style=none&echo=0'); $cat_list = str_replace('class="menu-item ', 'class="sub-menu-item ', $cat_list); echo $cat_list;меняются все классы menu-item, а нужно чтоб менялись только li входящие в sub-menu
<ul class="menu"> <li class="sub-menu-item menu-item-1"></li> <ul class="sub-menu"> <li class="sub-menu-item menu-item-2"></li> <li class="sub-menu-item menu-item-3"></li> </ul> </ul>подскажите пожалуйста реализацию такой генерации (добавить к sub-menu приставку sub например)
<ul class="menu"> <li class="menu-item menu-item-1"></li> <ul class="sub-menu"> <li class="sub-menu-item menu-item-2"></li> <li class="sub-menu-item menu-item-3"></li> </ul> </ul>или реализацию такой генерации (из sub-menu удалить menu-item )
<ul class="menu"> <li class="menu-item menu-item-1"></li> <ul class="sub-menu"> <li class="menu-item-2"></li> <li class="menu-item-3"></li> </ul> </ul>