Меню WordPress, все варианты

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

Довольно долгое время у блогеров не было выбора. Вплоть до версии 2.7 единственным способом сделать меню были только списки страниц и категорий. Позже добавили возможность автоматического добавления ссылки на главную к списку страниц, однако это не сильно облегчило ситуацию. И только с выходом WordPress 3.0 и функции wp_nav_menu стало возможно делать сколько угодно гибкое меню, с любыми данными и любой степени вложенности. Итак, пойдем в хронологическом порядке.

wp_list_pages

Функция выводит список страниц. Появилась еще в WordPress 1.5 и долгое время оставалась чуть ли ни единственным способом вывести меню. Опять же, из-за того, что других инструментов не было, разработчикам приходилось заставлять блогеров выстраивать структуру сайта на основе отдельных страниц, со всеми вытекающими отсюда программными костылями и извращениями.

Функция wp_list_pages имеет множество настроек и достаточно подробно описана в официальной документации. Поскольку такое меню довольно сложно кастомизировать, иногда можно встретить такой вариант вывода, он используется, например, для создания эффекта вкладок с динамической шириной:

Документация: wp_list_pages

wp_page_menu

Эта функция, по сути, делает то же самое, что и предыдущая, и добавляет автоматическую вставку ссылки на главную и возможность обернуть список div-блоком с заданным классом. Появилась в WordPress 2.7.

Документация: wp_page_menu.

wp_nav_menu

А вот эта функция специально создана для вывода меню. Я уже писал о ней в статье Адаптируем вывод меню для WordPress 3.0. С помощью этой функции можно создавать меню любой сложности и вставлять в него любые данные, доступные в WordPress. Давайте рассмотрим ее на примере выпадающего меню, которое я делал для Blackpig.ru. Для начала нужно создать само меню. Для этого добавьте в functions.php вашей темы следующие строки:

После этого в настройках меню появится вкладка «Navigation». Блок if проверяет наличие этого меню, и если оно не существует (вдруг удалили), создает его заново. Конечно, меню можно создать прямо в админке, однако я предпочитаю делать это в коде.

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

Этот код, т.н. walker, дает возможность изменить вывод меню, в данном случае добавляет класс parent для родительских элементов.

После этого подключаем любой скрипт выпадающего меню, например, Горизонтальное выпадающее меню на jQuery и вставляем вызов меню на страницу:

Документация: wp_nav_menu

С появлением wp_nav_menu все предыдущие способы вывода меню безнадежно устарели, поэтому я в своих проектах использую только ее, что и вам рекомендую.

P.S. Я сознательно не стал подробно расписывать такие моменты, как верстка меню, подключение скрипта и подробное описание параметров функций, так как эта статья не рассчитана на новичков и будет интересна, прежде всего, разработчикам тем для WordPress, которые и сами могут разобраться в документации. Тем не менее, я буду рад помочь освоить эту тему.

  • Как жаль, что я не разбираюсь ни в дизайне, ни в програминге

  • спасибо за то, что подсказали плагин и рассказали как им пользоваться

  • Да и вправду тут разбираться и разбираться)

  • Вовви

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

    • Вся кастомизация делается через CSS

  • Вовви

    Ну понятно. ну а если мне нужно сделать третьему например, отступ больше, чем для остальных

  • Подскажите, а насколько реально через walker класс сделать вывод в сайдбаре только вложенных элементов произвольного меню, при нахождения в них пользователя?

    Странно, что не предусмотрели такой возможности, ведь очень часто нужно чтобы в сайдбаре отображалось не все меню полностью. а только child-элементы.

    • Не вижу проблемы. Вставьте в меню только нужные пункты, они и выведутся.

      • Вы не поняли. Можно просто вывести все произвольное меню, да. А нужно только его часть, в зависимости от родительского пункта меню.

        Если в меню есть пункт
        Пункт1
        —Подрубрика1
        —Подруррика2
        —Страница1

        То при нахождении человека внутри пункта1, а именно в подрубрике1, подрубрике 2 и странице 1, должно отображаться меню только пункта1, а не других пунктов.

        Надеюсь, не запутанно объяснил.

        • Да, с произвольным так не получится. Как вариант, используйте wp_list_categories (или любую из подобных функций, которая может вывести дочерние элементы), и в параметре child_of вставляйте id текущей категории.

          • Да с этими функциями понятно, но у меня смешанное содержимое.

            Вроде нашел тут плагин, который с nav меню работает, правда не напрямую…надо будет попробовать. Иначе, walker мне не осилить.

  • oktano

    Прочитал статью, возникли вопросы. Как сделать так, чтобы выводился только первый уровень меню с определенным классом, который бы оформлял текущую категорию, где находится пользователь. И при этом, если пользователь находится в подкатегории, чтобы основная категория оставалась выделена и указывала на местоположение.

    Пример, есть категория «A», в ней подкатегория «Арбуз», когда пользователь находится в подкатегории, надо чтобы основная категория «А» была оформлена с использованием, например, класса «current». Спасибо.

  • oktano

    Пока предыдущий каммент на премодерации, хочу добавить, все что требовалось — удалось сделать с помощью приведенного выше скрипта. Возник другой вопрос: а можно сделать неактивными категории, в которых нет статей, а в активных категориях вывести количество содержащихся в них статей? Спасибо.

    • Да, можно, количество статей доступен как параметр

  • oktano

    Хорошо, немного перефразирую вопрос: «Как это сделать, что нужно указать в коде?» Только не отвечайте на «как» наречием «так».

  • Алоха!
    Вопрос на засыпку! Есть меню, есть пункт первого уровня и у него подпункты второго уровня. Как сделать так, чтобы подпункты второго уровня становились видными в меню только после перехода на их родительский пункт первого уровня?
    То есть перешел в раздел и раскрылся список его подразделов, а не так, чтобы он постоянно был виден изначально.

    • Нужно делать меню на списке рубрик. Т.е. написать функцию, которая будет выводить список дочерних рубрик текущей рубрики.

      • Просто надеялся, что можно как-то без написания новой функции. Там же в меню есть возможность перетащить один раздел к другому, сделать его как бы вложенным. Отображается в вертикальном меню соответственно, но выводится всегда.

        • Нет, стандартное меню статическое, как расставишь так и будет. А вы хотите динамическое, так что либо функция, либо поищите плагин, может кто-то уже написал решение.

  • Alexey

    Приветствую! Каким образом вывести произвольное поле в меню? На сайте по продаже недвижимости в поисковике есть произвольное поле, Имя Type, Значение For Sale и For Rent, мне необходимо их вывести в меню.

  • Данил

    А можно примеры (демо)?

    • Примеры в тексте. Если же вас интересует как верстать меню, то это другая тема.

  • Neolot, а как выделить выпадающую рубрику? Например добавить иконку или какой нибудь символ именно к рубрике, в которой есть выпадающие подрубрики. А если рубрика без подрубрик, чтобы символ не выводился. Надеюсь понятно объяснил 🙂

    • 1. У каждого пункта меню есть свой персональный класс, а имея класс, ему можно назначить иконку в css, например, с помощью background.
      2. Тут нужно проверять есть ли у пункта меню дочерний список UL. Если есть — значит выводить иконку. Это можно сделать либо с помощью walker для меню (см. статью), он присвоит родительскому пункту класс parent, либо сделать тоже самое с помощью jQuery.

  • Спасибо, Neolot 🙂

  • cooltext

    Neolot, я умею верстать, подготовил шаблон, решил его «одеть» на вордпресс, но сталкиваюсь с некоторыми трудностями по реализации. Например, у меня в одном пункте меню есть подпункты (в два столбца), они появляются сразу как только я навожу курсор на пункт меню. http://savepic.org/3906731.png
    Собственно как это реализовать и привело меня на твой форум. Но почитав, понял, что знаний недостаточно.
    Скажи пожалуйста, не собираешься ли ты написать статью как такое реализовать в WP?
    Посоветуй, как опытный человек, что мне учить и ковырять чтобы научиться «одевать» любые шаблоны на WP.

    • Для начала надо понимать, что «меню» — это всего лишь набор ссылок.
      Далее нужно знать что именно будет выводиться в этом меню.
      В большинстве случаев достаточно стандартного меню. Он простое и удобное, позволяет выводить любые ссылки.
      В более сложных случаях, например, нужно динамически выводить списком группы чего-либо, которые есть категории или метки, проще использовать функции для вывода списка категорий или тэгов.
      А иногда меню вообще не динамическое, а тупо забито в дизайне.
      Это общий принцип, смотри у себя по ситуации.

  • Доброй ночи, у такая проблема. Вообщем с созданием меню я разобрался , но хочу уточнить об одной детали. Когда я навожу курсором на меню раскрываются рубрики когда навожу курсором на рубрику выводится статься. Так вот я хочу чтобы эта самая статься при переходе на рубрику была видна! А то получается что сама рубрика пуста если по ней перейти у неё содержимого нет, а в меню наведя на неё курсором высвечивается статья.
    Может я совсем не умею объяснять ,вот мой сайт http://basketballforyou.ru/ в нём наведите на тренировки и на бросок высветится статья, а если просто нажать на бросок то этой статьи там не будет, а очень хочется чтоб была.

  • VRS

    Доброй ночи.
    Подскажите есть ли какой выход,
    Сейчас у меня такая таксономия

    произвольная ссылка href=»#»>> рубрика>> ее подрубрика >> запись

    И когда я на странице записи — произвольной ссылке НЕ присваивается класс current .

    Уже весь рунет и буржунет облазила в поисках решения. чтобы на странице записи присваивать current класс самому высшему родительскому пункту, если такой класс есть у дочернего. Не соображу как такой волкер написать (((
    Помогите, пожалуйста….

    • Я бы на вашем месте не заморачивался с вокером. Сделайте проверку и установку класса на jQuery.

  • А как просто перед добавить тег DIV, а затем закрыть его после завешения второго уровня меню? Это нужно чтоб сделать меню второго уровня выпадающим.

  • Сделал всё, как в описании, кроме подключения jQuery (не хочу выпадашек, хочу этажами; но это уже частности, насколько я понимаю). В админке меню увидел, ок. Но на страницах меню вообще не отобразилось. Тогда заменил в коде вывода « ‘Navigation’, ‘twentytwelve’» на « ‘Navigation’, ‘theme_location’» (я модифицирую одну из дефолтных тем Вордпресса). В ответ получил ошибку:

    «Notice: Trying to get property of non-object in /var/……./nav-menu-template.php on line 151 Notice: Trying to get property of non-object in /var/……./nav-menu-template.php on line 154 Notice: Trying to get property of non-object in /var/……./nav-menu-template.php on line 154 Notice: Trying to get property of non-object in /var/……./nav-menu-template.php on line 156»

    Что там починить?

    • Neolot

      Код walker уже не актуален, не используйте его.
      За последние 3 года, которые прошли с момента публикации статьи, в меню WP внесли много изменений. Теперь там навешивается классов больше чем достаточно.