Создание меню на WordPress

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

Описание всех упоминаемых функций в статье смотрите в Кодексе WordPress.

Содержание статьи

  1. Разметка
  2. Перенос меню на WordPress
  3. Добавление формы поиска в меню
  4. FAQ по меню

Разметка

Итак, в качестве примера предлагаю рассмотреть меню на данном ресурсе:

Меню
Внешний вид навигации

Ваша навигация может выглядеть иначе и пункты называться по-другому, но это не важно. Чтобы сделать задачу чуть сложнее, я специально подобрал вариант с поисковой формой.

Во-первых, прежде чем переносить все на CMS, желательно окончательно закончить с версткой, чтобы в дальнейшем она не отвлекала от натяжки на движок. Так будет намного удобнее. Впрочем это касается всех систем управления контентом, не только WP.

Разметка демо-примера достаточно банальная и у искушенного специалиста не вызовет особенного интереса (см. «Верстка меню сайта»):

<nav class="wrap-menu">
  <ul id="menu" class="menu">
    <li class="current">
      <a href="#">Главная</a>
    </li>
    <li>
      <a href="#">HTML/CSS</a>
    </li>
    <li>
      <a href="#">WordPress</a>
    </li>
    <li>
      <a href="#">Справочник</a>
    </li>
    <li>
      <a href="#">О блоге и авторе</a>
    </li>
    <li class="wrap-search">
      <button id="search-btn" class="search-btn"></button>
      <form action="#" id="search-form" class="search-form">
        <input type="search" id="s" class="s" value="Поиск..." placeholder="Что ищем?">
        <input type="submit" value="Ok">
      </form>
    </li>
  </ul>
</nav>

Для удобства (но необязательно) при дальнейшей работе можно назначить классы элементам <li> в разметке, либо сделать это динамически через JS. Это имеет смысл, если пункты меню незначительно отличаются друг от друга, имеют различные бэкграунды и т.д.

Оформление CSS в статье не рассматривается, так что будем считать, что заготовка завершена.

Перенос меню на WordPress

Первый вариант

Подключим поддержку произвольного меню в текущей теме WP, добавив в файл functions.php PHP-код:

add_theme_support('menus');
/* здесь и далее дескрипторы <?php ?> опущены */

Заходим в админку, пункт Внешний вид → Меню. В поле Заголовок меню введем любое название:

Заголовок меню
Заголовок меню

Займемся прописыванием пунктов навигации. Как можно заметить, в данном окне предлагается на выбор три варианта пунктов — это произвольные ссылки, страницы и рубрики. Перед формированием произвольного меню важно понимать различие между ними. На страницах отображается статическая информация — к этому понятию у нас подходят пункты «Справочник» и «О блоге и авторе». В то время как в рубриках может быть несколько записей, например несколько статей по верстке в рубрике «HTML/CSS верстка». Произвольная ссылка может быть ссылкой на сторонний ресурс или ссылка на главную страницу вашего ресурса к примеру. Главная страница в WP может показывать как статический контент, так и последние записи (блоговый движок все-таки). Таким образом получаем следующее:

  • Страницы — «О блоге и авторе», «Справочник»
  • Рубрики — «HTML/CSS», «WordPress», «Вебмастеру»
  • Произвольные ссылки — «Главная»

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

Рубрики, страницы и произвольные ссылки
Формируем пункты навигации

Добавляем необходимые пункты в новоиспеченное меню, методом drag&drop расположите их в том порядке, в котором предпочтете нужным. Как видите, WP позволяет настраивать навигацию прямо в админке, без копания в коде. Однако кое-какие манипуляции с шаблоном все-таки надо провести. Зайдем в файл темы, где должна выводиться навигация и воспользуемся функцией wp_nav_menu():

wp_nav_menu('menu=Название меню'); // в нашем случае menu

Второй вариант

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

register_nav_menus(array(
  'header_menu' => 'Меню в header',  
  'sidebar_menu' => 'Меню в sidebar' 
));

Здесь ключи массива — произвольные названия меню в шаблоне, значения — описания, выводятся в админке WP.

Далее проследуем в файл шаблона, куда нужно вставить навигацию, и пропишем код:

wp_nav_menu(array(
  'theme_location' => 'header_menu' // расположение меню в теме, вывели header_menu
));

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

Области темы
Области вывода навигации

Настройка навигации

Если вы все сделали правильно, навигация появится в вашем проекте, однако скорее всего будет выглядеть неоформленной. Дело в том что движок по умолчанию генерирует свои классы и id. Первый вариант — это изменить правила для элементов в style.css на «вордпрессовские» (лучше всего через Firebug). Второй — указать в аргументах wp_nav_menu() классы, которые мы хотим видеть. В качестве аргумента функция принимает массив, в котором можно переопределить стандартные настройки:

wp_nav_menu(array(
  'menu' => '', // название меню
  'container' => 'div', // контейнер для меню, по умолчанию 'div', в нашем случае ставим 'nav', пустая строка - нет контейнера
  'container_class' => '', // класс для контейнера
  'container_id' => '', // id для контейнера
  'menu_class' => '', // класс для меню
  'menu_id' => '', // id для меню
));

Этих ключей массива вполне хватит для нашего примера, на самом же деле их еще довольно много, что позволяет гибко настраивать навигацию.

Полученное DOM дерево в Firebug
Полученное DOM дерево в Firebug. Классы и id для <li> сгенерированы WP

Добавление формы поиска в меню

Меню выведено, но остался еще один нюанс — поисковая форма. Первое решение, которое приходит в голову, немного изменить разметку, вынести поиск в отдельный элемент, скажем <div>, и допилить шаблон:

  <?php wp_nav_menu(array(...)); ?> <!-- навигация -->
  <div class="wrap-search">
    <!-- поисковая форма -->
  </div>

Однако это не совсем удобно — приходится править код, переназначать стили и т.д. Я нашел более удобный вариант решения:

/* Добавляем поиск */
add_filter('wp_nav_menu_items','add_search', 10, 2);
function add_search($items, $args) {
  ob_start();
  get_search_form();
  $search_form = ob_get_contents();
  ob_end_clean();
  $items .= '<li class="search-item">' . $search_form . '</li>';
  return $items;
}

А в search-form.php дописываем остальную разметку:

<button id="search-btn" class="search-btn"></button>
<form action="#" id="search-form" class="search-form">
  <input type="search" id="s" class="s" value="Поиск..." placeholder="Что ищем?">
  <input type="submit" value="Ok">
</form>

Теперь все в порядке.

FAQ по меню

Как назначить отдельный стиль для активного пункта меню?

Часто в Сети встречаются меню с выделенными активными пунктами, например с подчеркиванием, другим фоном и т.д. При верстке многие назначают другой стиль пунктам через класс .active. Однако WP добавляет к активным пунктам класс .current-menu-item, поэтому просто надо переменить название класса на .current в style.css:

.current-menu-item {
   /* стили для активного пункта */
}

Рейтинг статьи

Похожие статьи

Комментарии читателей

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

    (на странице поста — выводить тайтл, на всех других — зона для виджета)
    Я уже голову сломал :(

  2. Спасибо за полезную и интересную информацию!

  3. Люси:

    Здравствуйте. Подскажите плж. У меня есть следующий код CSS background: # dc3522 none repeat scroll 0 0;
    color: #ffffff;
    font-weight: 500;
    line-height: 35px;
    font-size: 18px;
    overflow: hidden;
    margin-bottom: 20px;
    Этот код дает оформление, как на этой картинке https://pp.vk.me/c626718/v626718226/2aa28/I4cEhhstQZA.jpg
    А как сделать как на второй — два цвета? http://oi66.tinypic.com/sqi2yh.jpg
    Заранее спасибо.

    • Добрый день, как вариант https://jsfiddle.net/amezbw9u/1/
      Угол задается здесь: transform: skewX(-20deg);

      • Люси:

        Спасибо. но https://jsfiddle.net/amezbw9u/1/ не могу открыть….
        transform: skewX(-20deg) прибавила к коду своему, но не вышло

        • Ссылка не открывается?
          http://codepen.io/anon/pen/kkwjPm то же самое на Codepen.

          • Люси:

            Открылось! Спасибо! Это как раз то, что нужно сделать!
            А как мне это применить к моему коду? у меня класс .dotted
            list заменить на .dotted? яправильно поняла? или еще код хтмл надо куда-то добавить?

          • Скиньте свою разметку html или url.

          • http://codepen.io/anon/pen/ZpJVKW — обновленный пример
            Текст внутри заголовка оборачиваете в еще один элемент (span в примере, добавить нужно в шаблоне вашей темы) с нужным классом, и добавляете тот css, что написан.

          • Люси:

            Добрый вечер, Вадим! Преогромнейшая Вам благодарность! У меня почти получилось по Вашей инструкции! Только почему-то угол не на всю высоту заголовка. Не подскажите, что не так сделала? Тоже самое и в верхнем горизонтальном меню (сделала при наведении на ссылку выделение др. цветом), но выделение не на всю высоту меню… как исправить?

          • У .dotted внизу отступ. Уберите его: padding-bottom: 0. В меню тоже внутренние поля http://www.screencapture.ru/file/b2229D5a Убираете их .header_menu_res и внутреннего #menu-header, добавляете для ссылок http://www.screencapture.ru/file/CBfc381f

          • Люси:

            Вадим, спасибо Вам огромное! Очень помогли!
            А что править в внутреннем #menu-header? у этого класса не прописано padding. я просто добавила padding-bottom: 0px, но небольшой отступ в меню все же есть и в выпадающем тоже (особенно внизу). и футер тоже очень широкий. проставила padding-bottom: 0px; но не помогло. высоту прописывала тоже не меняется. подскажите плж в чем ошибка?
            и еще не подскажите как сделать на мое верхнее меню хоум иконку, как в меню по ссылке? http://user5chnik.srf.wh1.su/boltalka/

            Заранее Большое Спасибо. И простите, что завалила Вас вопросами.

          • В #menu-header надо margin’ы вверху и внизу убрать и вместо них добавить padding’и на те же значения для ссылок, чтобы осталось внешне также. Для внутреннего меню — padding-bottom: 0. В футере пустой элемент .dotted — удаляйте, и с высотой станет все нормально. Иконку меню возьмите с шаблона, где она у вас есть уже, вставьте в нужный шаблон и стилизуйте также. Все оставшиеся вопросы лучше в скайп vadim_bogomazov или вк.

  4. Cat:

    Очень большое спасибо, Вадим! Несколько дней «бился» с астивным пунктом навигации. Помог Ваш совет:
    .current-menu-item, .current-menu-item a {
    /* стили для активного пункта */
    }

  5. Спасибо Огромное за статью !!!!!!!!!!!!!!!!!!!!!!!!!

  6. Здравствуйте. У меня валидатор показывает однотипные ошибки в меню, типа вот таких: «Duplicate ID menu-item-431». Чёткого ответа на вопрос, как исправить эту ошибку нагуглить не смог, но что-то мне подсказывает, что в коде я должен вместо «ID» прописать «menu-item-«. Среди файлов темы есть вот такой файл — menu_option.php, в котором встречается и «menu-item-» и «ID», но где надо произвести эту замену не совсем понял. Не подскажете, что надо поправить в коде? Буду признателен за помощь.

  7. Никита:

    Вот такая проблема. Тема по умолчанию поддерживает только 1 меню. Когда добав ляю еще одно, (в админке 2 разных) оно автоматически дублируется и получается 2 одинаковых меню, хотя они должны быть разными, в чем проблема?

  8. VladShvets:

    Здравствуйте, можно ли прикрутить в WP своё меню которое сделал в ручную имея html файл и папку с картинками кнопок?

    • Можно: создаешь меню в админке, добавляешь пункты, через CSS прописываешь стили. Если для каждой кнопки отдельное изображение, по уникальному id или классу прописываем путь к изображению.

  9. Отлично все рассказано! Автору благодарность!

  10. Здравствуйте.
    У меня сложность возникла. Редактор меню на ВП глючит.
    Не дает создавать иерархию страниц. То есть все списком выводит.
    Я добавляю страницы, наполняю сайт и он перестал создавать мне подменю. Я уж и произвольно делал страницу, через «Ссылки», задавая название и ссылку данному подменю, но все равно ВП выводит страницу списком.
    У меня очень разветвленное меню на сайте и четкая иерархия.
    Удалил все, чтобы создать заново — в итоге вообще меню нет на сайте.
    Что делать?
    Можете подсказать?

  11. Алекс:

    в общем 2 меню боковое и под шапкой с такой функцией у меня форма поиска встала в оба меню как сделать только одну форму в верхнем меню?

    • Вставьте через функцию get_search_form() в том шаблоне, где у вас меню находится. Таким образом вставится поисковая форма из шаблона searchform.php, если такого шаблона в теме нет, будет дефолтная форма поиска.

  12. Дмитрий:

    спасибо за статью.
    вопрос по главной странице, использую бесплатный шаблон boldy, данный шаблон не имеет в меню пункт «Главная», если не ошибаюсь данный пункт можно прописать в header.pgp или page.php, подскажите если не затруднит куда именно.
    Если создать просто страницу «Главная», при переходе в адресной строке будет
    http://www.mysite.ru/glavnaya

    • Попробуйте в functions.php добавить этот код
      function home_page_menu_args( $args ) {
      $args['show_home'] = true;
      return $args;
      }
      add_filter( 'wp_page_menu_args', 'home_page_menu_args' );

      После в админку, внешний вид -> меню -> страницы -> «все»
      Скрин

      • Дмитрий:

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

  13. Андрей:

    Что-то не работает этот параметр


    'container' => 'nav',

    все равно в div оборачивает, как исправить?

  14. jet:

    display:inline надо применять для «li» элементов, а не для ul.

    Подскажите пожалуйста по поводу активных пунктов меню, смотрю в firebug там присваивает классы current- но дальше дописывает код. Т.е. простое добавление в css файл класса .current не работает к активному элементу. Как быть?

    И у вас кстати регулярка на проверку имени не правильная. У вас написано пример «Иван Иванов» а в регулярке допустимы только буквы. Т.е. 2 слова не введешь.

  15. Ivan:

    Tank: чтобы выстроить в ряд надо float:left приписать к li.

  16. Tank:

    подскажите если не трудно! что-то не могу li в ряд поставить display:inline для ul не работает((((

  17. Мария:

    Спасибо ребята!

Добавить комментарий