Меню в WordPress. Волкер меню.

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

Также в меню WordPress вы можете изменять порядок элементов банальным перетаскиванием.

Давайте подробно рассмотрим весь процесс добавления меню. Для начала переходим в админке во Внешний вид > Меню… У вас нет такого пункта? Окей, значит вашей темой меню не поддерживаются, сейчас мы это исправим, рассмотрим даже два способа.

Способ 1. Включение поддержки меню в теме WordPress

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

add_theme_support('menus');
Функционал меню в WordPress

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

Способ 2. Регистрация областей темы

В двух словах, область темы — это такая условная область, которая предназначена для вывода меню. Условная, потому что сама по себе она нигде не выводится. Как всё это происходит по порядку:

  1. Сначала мы регистрируем область темы. После этого у нас сразу появляется функционал меню тут: Внешний вид > Меню. Допустим мы создадим две области темы: «Шапка сайта» и «Левый сайдбар».
  2. Затем, при создании меню мы указываем область темы, в которой хотим отображать данное меню. Также можно указать несколько областей сразу.
  3. И завершающий шаг. В разных частях темы выводим меню, соответствующие разным областям.

Не знаю, насколько понятно я всё это объяснил в теории, но на практике определенно будет легко. Итак, для того, чтобы зарегистрировать область темы, нам понадобится функция register_nav_menus(). Давайте тогда создадим две области, о которых я писал выше: «Шапка сайта» и «Левый сайдбар».

Да, код — в functions.php.

register_nav_menus(
	array(
		'head_menu' => 'Шапка сайта',
		'side_menu' => 'Левый сайдбар'
	)
);

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

Давайте теперь разберемся, как создавать и как управлять меню. В принципе в админке WordPress всё сделано интуитивно, но на всякий случай мы всё подробно рассмотрим.

Переходим во Внешний вид > Меню, указываем в поле название нового меню и нажимаем кнопку Создать меню.

Создаем новое меню в админке сайта

В итоге у нас получилось вот что:

Страница редактирования меню в WordPress.

Теперь, используя колонку со списком страниц и рубрик, давайте заполним меню.

  • Для того, чтобы добавить один или несколько элементов в меню, просто отметьте их галочкой и нажмите кнопку Добавить в меню.
  • Если вы не видите нужной вам страницы в списке, перейдите на вкладку «Все» либо воспользуйтесь вкладкой «Поиск».
  • Для того, чтобы добавить в меню ссылку на главную страницу, в списке страниц перейдите на вкладку «Все», отметьте галочкой элемент «Главная» и добавьте его в меню.
  • По умолчанию в меню можно добавлять только страницы, рубрики и произвольные ссылки. Если вам нужно добавить в меню произвольный тип поста, элементы созданной вами таксономии или записи, перейдите по этой ссылке.
  • Вы можете изменять порядок элементов перетаскиванием.
  • Также, чуть перетащив элемент вправо, его можно сделать дочерним для вышестоящего элемента. Дочерние элементы можно будет реализовать в виде выпадающего списка на сайте.
  • Если отметить галочкой «Автоматически добавлять в это меню новые страницы верхнего уровня», то, после публикации новох страниц, они автоматически будут добавляться в конец этого меню (тогда такое меню лучше будет добавлять в сайдбар, так как в шапке может просто не хватить места).
  • Отметьте галочкой области темы, в которой вы хотите отобразить это меню.

Всё получилось? Тогда нажимаем кнопку Сохранить меню.

Меню WordPress.

Вы можете удалить или отредактировать (переместить, переименовать) элемент, нажав на стрелку справа (на скриншоте отмечена красным).

Редактировать элемент меню.

Сохранили своё меню? Тогда перейдите на вкладку Управление областями, тут вы также сможете назначить меню для областей сайта, очень удобно, если у вас на сайте много менюх и много зарегистрированных областей.

Управление областями темы.

CSS-классы для отдельных элементов меню, открытие некоторых ссылок в новой вкладке

Как?

На первый взгляд кажется, что таких настроек в админке нет, и, чтобы добавить для какого-то определенного элемента меню CSS-класс, нужно колдовать в коде, но на самом деле это не так.

Видите в правой верхней части экрана вкладки «Настройки экрана» и «Помощь»? Нам нужна первая. Кликаем по ней, после чего у нас выпадает блок, в котором можно включить дополнителные настройки элементов меню.

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

Дополнительные настройки элементов меню.

Как добавлять в меню записи, таксономии и произвольные типы постов

На предыдущых скриншотах видно, что по умолчанию в меню можно добавлять только страницы, ссылки и рубрики. А если нам надо добавить запись? Конечно, вы можете добавить её через «ссылки», но тогда, если изменится URL записи, у нас появится ошибка 404.

Решение этой задачи есть и оно очень простое.

Записи и метки

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

Добавляем записи и метки в меню WordPress.

Таксономии и типы постов

И у тех и у других принцип один и тот же — при регистрации таксономии (register_taxonomy()) или типа поста (register_post_type()) значение параметра функции show_in_nav_menus должно быть true.

register_taxonomy('mytaxonomy',
		array('post'),
		array(
			...
			'show_in_nav_menus' => true,
			...
		)
);
$args = array(
	...
	'show_in_nav_menus' => true,
	...
);
register_post_type('product',$args);

Если после этого элементы таксономии или типы записей так и не появились в меню, в правом верхнем углу страницы откройте вкладку «Настройки экрана» и включите их там.

Вывод меню на сайте

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

Пример 1. Используем для вывода ID / ярлык / название меню

Если вы всё-таки захотите использовать этот первый способ, я рекомендую в качестве параметра задавать только ID меню. Читайте подробнее о том, как узнать ID меню или его ярлык.

В итоге имеем:

$args = array(
	'menu'	=> 381
);
wp_nav_menu( $args );

Пример 2. Использование зарегистрированных областей темы для вывода меню

На первый взгляд, этот пример может показаться сложнее, потому что сначала нам требуется зарегистрировать область темы (в этом посту мы уже зарегали две области — head_menu (Шапка сайта) и side_menu (Левый сайдбар), затем, при создании меню, нам надо присвоить его одной из этих областей (мы уже создали с вами меню и присвоили его области head_menu) и только после этого мы можем выводить область с содержащимся в ней меню на сайте.

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

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

$args = array(
	'theme_location' => 'head_menu'
);
wp_nav_menu( $args );

Функция wp_nav_menu() имеет большое количество параметров, все они описаны в документации этой функции.

Вставляем меню в сайдбар (в виде виджета)

Существует ещё и третий способ вывода меню на сайте — в виде виджета. Для этого переходим во Внешний вид > Виджеты, находим виджет «Произвольное меню» и перетаскиваем его в сайдбар. Если по каким-то причинам у вас не получается это сделать, сначала прочитайте пост про сайдбары в WordPress.

Виджет меню в WordPress

Переделываем меню при помощи волкера

Рассмотрение класса Walker безусловно заслуживает отдельного поста. Сейчас я покажу лишь простой пример, который позволит вам использовать этот класс при выводе меню, тем самым подстраивая его под свой сайт, меняя HTML-разметку, добавляя различные атрибуты элементам и PHP-условия.

Для начала нужно создать класс, у меня это True_Walker_Nav_Menu, код которого я вставил в functions.php текущей темы.

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

class True_Walker_Nav_Menu extends Walker_Nav_Menu {
	/*
	 * Позволяет перезаписать <ul class="sub-menu">
	 */
	function start_lvl(&$output, $depth) {
		/*
		 * $depth – уровень вложенности, например 2,3 и т д
		 */ 
		$output .= '<ul class="menu_sublist">';
	}
	/**
	 * @see Walker::start_el()
	 * @since 3.0.0
	 *
	 * @param string $output
	 * @param object $item Объект элемента меню, подробнее ниже.
	 * @param int $depth Уровень вложенности элемента меню.
	 * @param object $args Параметры функции wp_nav_menu
	 */
	function start_el(&$output, $item, $depth, $args) {
		global $wp_query;           
		/*
		 * Некоторые из параметров объекта $item
		 * ID - ID самого элемента меню, а не объекта на который он ссылается
		 * menu_item_parent - ID родительского элемента меню
		 * classes - массив классов элемента меню
		 * post_date - дата добавления
		 * post_modified - дата последнего изменения
		 * post_author - ID пользователя, добавившего этот элемент меню
		 * title - заголовок элемента меню
		 * url - ссылка
		 * attr_title - HTML-атрибут title ссылки
		 * xfn - атрибут rel
		 * target - атрибут target
		 * current - равен 1, если является текущим элементом
		 * current_item_ancestor - равен 1, если текущим (открытым на сайте) является вложенный элемент данного
		 * current_item_parent - равен 1, если текущим (открытым на сайте) является родительский элемент данного
		 * menu_order - порядок в меню
		 * object_id - ID объекта меню
		 * type - тип объекта меню (таксономия, пост, произвольно)
		 * object - какая это таксономия / какой тип поста (page /category / post_tag и т д)
		 * type_label - название данного типа с локализацией (Рубрика, Страница)
		 * post_parent - ID родительского поста / категории
		 * post_title - заголовок, который был у поста, когда он был добавлен в меню
		 * post_name - ярлык, который был у поста при его добавлении в меню
		 */
		$indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
 
		/*
		 * Генерируем строку с CSS-классами элемента меню
		 */
		$class_names = $value = '';
		$classes = empty( $item->classes ) ? array() : (array) $item->classes;
		$classes[] = 'menu-item-' . $item->ID;
 
		// функция join превращает массив в строку
		$class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args ) );
		$class_names = ' class="' . esc_attr( $class_names ) . '"';
 
		/*
		 * Генерируем ID элемента
		 */
		$id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args );
		$id = strlen( $id ) ? ' id="' . esc_attr( $id ) . '"' : '';
 
		/*
		 * Генерируем элемент меню
		 */
		$output .= $indent . '<li' . $id . $value . $class_names .'>';
 
		// атрибуты элемента, title="", rel="", target="" и href=""
		$attributes  = ! empty( $item->attr_title ) ? ' title="'  . esc_attr( $item->attr_title ) .'"' : '';
		$attributes .= ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
		$attributes .= ! empty( $item->xfn )        ? ' rel="'    . esc_attr( $item->xfn        ) .'"' : '';
		$attributes .= ! empty( $item->url )        ? ' href="'   . esc_attr( $item->url        ) .'"' : '';
 
		// ссылка и околоссылочный текст
		$item_output = $args->before;
		$item_output .= '<a'. $attributes .'>';
		$item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
		$item_output .= '</a>';
		$item_output .= $args->after;
 
 		$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
	}
}

Если вам нужны ещё параметры объектов $item, смотрите документацию функции wp_get_nav_menu_items(), которая кстати является ещё одним нестандартным способом вывода меню в WordPress.

Окей, класс вставили, второй шаг — добавить параметр walker в функцию wp_nav_menu(). То есть, если у вас уже используется меню на сайте, не нужно менять его код на тот, который указан тут ниже, надо всего лишь добавить туда ещё один параметр.

$args = array(
	'theme_location' => 'head_menu',
	'walker'=> new True_Walker_Nav_Menu() // этот параметр нужно добавить
 
);
wp_nav_menu( $args );

Вот и всё, теперь, редактируя класс, вы сможете отредактировать и ваше меню. Всё просто. И для полной радости ещё и видео по волкерам:

Миша Рудрастых

Впервые познакомился с WordPress в 2009 году. С 2014 года меня можно встретить на WordCamp — официальной конфе по WordPress, иногда там выступаю. Также в настоящее время веду курсы по WordPress в Epic Skills.

Если вам нужна помощь с вашим сайтом или может даже разработка с нуля — пишите мне.

Комментарии 74

  • Роман:

    Хороший урок. Жаль я уже сделал менюшку на WP 4.1 theme Twenty Fifteen. Мне пригодилось бы. А так пришлось фактически интуитивно, используя код самой темы переделывать, в сети не так уж и много уроков нормального качества на данную тематику, искать было в лом (копошиться в гуано, если честно).
    Вы бы поковырялись в Twenty Fifteen, уроков про неё сделали бы. Тема просто обалденная, хотя и отличается под капотом. Могу даже список первоочередных вопросов написать /те, которые возникают почти сразу после активации темы/.

    • Миша:

      Напиши, я и читатели моего блога будут благодарны )

      • Роман:

        Да, я считаю, что пора сделать статью про "Twenty Fifteen". Эта дефолтная тема по своему уникальна и её необычность не только в концепции дизайна. Дело в том, что внимательному глазу открывается простая истина - она вообще не заточена под банерную рекламу.
        Глядя на неё, сама мысль поставить баннер или сделать длинное меню с прокруткой (через виджеты, к примеру) кажется кощунственной. В ней явственно чувствуется "мобильные" корни, т.е. создали её для мобильных гаджетов, а после приспособили для настольных наших, родных...
        И это сказывается на очень даже на многом. Я поковырялся тут под капотом и могу заявить, что настроить прокрутку сайдбара не проблема, как и сделать уже его, но... Но тогда вы можете просто скачать тему "Fukasawa" и через CSS закрепить её сайтбар - то же самое.
        Нет, очарование и изюминка (есть они в ней, есть) заключаются именно в тех пропорциях, что в ней от рождения.
        Что может заинтересовать юнного кастомайзера?
        Наверное, следующее:
        совместимость с популярными плагинами (многие прошлогодние конфликтуют, а уж двух-трех летние...особенно если их несколько, вообще убивают), как убрать дату(полностью), автора (полностью), как отрегулировать ширину сайтбара, способ уменьшения длинны белых линий, разделяющих меню, как убрать полосу прокрутки на сайтбаре, как заменить социальное меню на подобное верхнему (с его свойствами), как сочетать цвета в теме (там дается три цветового поля и их нужно подобрать, дабы не отпугивали посетителей).
        Вышеперечисленный список - это те вопросы, что у меня возникли в перые полчаса общения с 2015. И вот уже несколько дней я её тестирую. Совершенно честным образом я пытаюсь уйти от неё, бросить сие чудовище, но... вот уже полтора десятка тем проиграли соревнование (готовлю к запуску пару сайтов). Я все время возвращаюсь к ней, ведь разработчик этого чудовища следовал столь почитаемому мной девизу: Совершенство - это когда нечего отнять.
        Я отнял, не было там совершенства. Убрал футер (визуально полностью), заменил виджет на второе меню (статьи выводяться через пункты меню), убрал прокрутку (сайтбар полностью зафиксированн).
        ...и... теперь смотрю на это совершенство и понимаю, какой чудовищный заговор готовят крупнейшие игроки интернета (типа Гугола и иже с ним). Слишком глубоко проработанна и измененна парадигма сайтостроения при разработке этой темы. Не верю я в то, что разработчики ВП "просто решили", слишком коренные изменения проглядывают за этим.
        И все это оч. неплохо укладывается в то, что мы видим в политике развития Гугла или того же Яндекса. Грядут перемены. Большие. Как люди, по полёту ласточки предсказывают дождь, так и выход этой темы (как подтверждение появления такого подхода, вспомним Виндовс с его Метро и плоским дизайном), сигнализирует о Новой Волне.
        Станем ли мы новыми серферами или будем поглощенны изменениями - зависит от нас. А я призываю: "Все на покорение 2015"!

  • Григорий:

    А где закрывается тег li?
    Дизайн таков, что нужно html код меню усложнить, но закрывающиеся li-шки остаются

  • Григорий:

    Спасибо за ответ
    Не особо удобно, когда что-то где-то вшито и находится в кукуево)
    Пришлось nav-menu-template дорабатывать

  • Толя:

    на моем сайте http://sweethomeua.com/ на главной странице при выборе в меню: открытки-события, меню пропадает под слайдером, как сделать поверх слайдера? Тема Twenty Twelve

  • VRS:

    А можно как-то прикрепить walker к тем меню, которые выводятся через виджеты?

  • Алексей:

    Здравствуйте Михаил! Подскажите пожалуйста при использование Walker в вашем примере кода как можно удалить полностью class=" " у элемента li Если удаляю строчку

    $class_names = ' class="' . esc_attr( $class_names ) . '"';

    то class=" " у элемента li удаляется. Но тогда активный пункт меню выглядит так

    <licurrent-menu-item></licurrent-menu-item>

    при этом пропадает выделение пункта меню

  • Алексей:

    class=" " у элемента li удалился но теперь не выделяется активный пункт меню это можно как нибудь поправить?

  • Dennis:

    Присоединяюсь к вопросу. Как избавиться от всех классов, кроме активного пункта меню???

  • VRS:

    Привет, Миш.
    Ты не подскажешь, может видел плагин или код, чтобы сделать как тут https://core.trac.wordpress.org/ticket/14134#comment:17 . Чтобы можно было сохранять отдельно каждый пункт меню, а не всё целиком.

    • Миша:

      Привет!
      Увы не знаю. Но идея очень интересная, уже хочу написать об этом 🙂

      • VRS:

        Будет интересно почитать). Я гуглила всю ночь, но такого не нашла.
        Единственно, сейчас сижу размышляю, что если записывать только один пункт, то следующий после него будет иметь тот же порядковый номер расположения в меню..
        В общем буду очень ждать твоих новых статей.
        Пользуясь случаем - Спасибо. Очень часто меня твой блог выручает).

  • Владимир:

    Тема отличная.
    Вопрос по этой теме ВАЛКЕРа:
    Можно ли при помощи этой функции вывести количество записей как выводит их стандартное меню категорий.
    Если да то как это сделать опиши пожалуйста?

  • Владимир:

    Вот картинка http://i.stack.imgur.com/IfCjq.jpg.

  • Владимир:

    можно ли сделать так как на картинке с помощью WALKER'a если ДА то как это написать?

    • VRS:

      Попробуйте так

      В function start_el

      global $wp_query;  
      $count_category = '';
      if($item->object == 'category')  { 
      $cat_id = $item->object_id;
      $count_category = get_category($cat_id)->category_count;
      }
      // И дальше в районе
      // ссылка и околоссылочный текст
      // добавляете 
      		//....
      		$item_output .= '(' . $count_category  . ')';
      		$item_output .= '</a>';
      		//....
      • Владимир:

        Извините меня. Но я только пытаюсь понять как этот Walker код работает. У меня появились только скобки () а дальше я так понимаю мне нужно изменить в этом коде:

        global $wp_query;  
        $count_category = '';
        if($item->object == 'category')  { 
        $cat_id = $item->object_id;
        $count_category = get_category($cat_id)->category_count;
        }

        так чтобы моя произвольная таксономия показывала количество записей?
        я использую такой код в function.php :

        <pre lang="htaccess">add_action( 'init', 'prowp_publishing_taxonomy' );
        function prowp_publishing_taxonomy() {
        	$labels = array(
        		'name' 				=> 'Категории',
        		'singular_name' 	=> 'Категория',
        		'search_items' 		=> 'Найти Категорию',
        		'all_items' 		=> 'Все категории',
        		'parent_item' 		=> 'Родительская категория',
        		'parent_item_colon' => 'Родительские категории:',
        		'edit_item' 		=> 'Редактировать категорию',
        		'update_item' 		=> 'обновить категорию',
        		'add_new_item' 		=> 'Добавить новую категорию',
        		'new_item_name' 	=> 'Новое название категории',
        		'menu_name' 		=> 'Категории'
        	);
        	$args =array(
        		'labels'	   => $labels,
        		'hierarchical' => true,
        		'query_var'	   => true,
        		'rewrite' 	   => true
        	);
        	register_taxonomy( 'type', 'publishings', $args );
        }
  • Владимир:

    В sidebar вложен виджет произвольное меню в котором выбирается нужное меню из списка уже созданных (меню1, меню2, меню3 ...). Задача чтобы в произвольном меню на странице1 было меню1, на странице2 было меню2 и т.д. Возможно ли с помощью True_Walker_Nav_Menu это реализовать? Извините, если что не так написал, я еще мало разбираюсь в этом.

    • Миша:

      У меня для вас хорошая новость — колдовать с волкером не придется, вот эта функция вам поможет the_widget() ну и условные теги, is_page() я так полагаю.

      • Владимир:

        Только у меня их три. Как определить в какой?

      • Владимир:
        if ( is_page( 'сраница1' ) ) {	
        	if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar('Контент слева') ) {  the_widget( 'WP_Nav_Menu_Widget', array('nav_menu' => 'Меню1_1') );} 
        	if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar('Контент центр') ) { the_widget( 'WP_Nav_Menu_Widget', array('nav_menu' => 'Меню1_2') );} 
        	if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar('Контент справа') ) { the_widget( 'WP_Nav_Menu_Widget', array('nav_menu' => 'Меню1_3') ); } 
        }
        if ( is_page( 'сраница2' ) ) {	
        	if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar('Контент слева') ) {  the_widget( 'WP_Nav_Menu_Widget', array('nav_menu' => 'Меню2_1') );} 
        	if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar('Контент центр') ) { the_widget( 'WP_Nav_Menu_Widget', array('nav_menu' => 'Меню2_2') );} 
        	if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar('Контент справа') ) { the_widget( 'WP_Nav_Menu_Widget', array('nav_menu' => 'Меню2_3') ); } 
        }
        if ( is_page( 'сраница3' ) ) {	
        	if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar('Контент слева') ) {  the_widget( 'WP_Nav_Menu_Widget', array('nav_menu' => 'Меню3_1') );} 
        	if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar('Контент центр') ) { the_widget( 'WP_Nav_Menu_Widget', array('nav_menu' => 'Меню3_2') );} 
        	if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar('Контент справа') ) { the_widget( 'WP_Nav_Menu_Widget', array('nav_menu' => 'Меню3_3') ); } 
        }

        Я правильно думаю? подскажите пожалуйста

  • Владимир:

    Спасибо. Я так полагаю надо так?

    is_page( 'Страница1' ) the_widget( 'WP_Nav_Menu_Widget', array('nav_menu' => 'Меню1') );
    is_page( 'Страница2' ) the_widget( 'WP_Nav_Menu_Widget', array('nav_menu' => 'Меню2') );
  • VRS:

    Привет, Миш).
    Ты не в курсе, есть ли способ сортировать wp_nav_menu как wp_page_menu по post_title ?

  • JaRule:

    Здравствуйте Михаил!
    Сразу оговорюсь что опыта разработки на php у меня очень мало, а с классами на нем и вовсе не работал никогда. Вопрос такой: изначально мне нужно сделать верхнее меню в теме которая таковые не поддерживает. Я сделал все по тексту, и класс вставил тоже. Меню вверху появилось, только оно идет в столбик (пункт1, строчкой ниже пункт2 и т.д.) а как сделать чтобы оно было в строчку (пункт1, правее пункт2 и т.д.), и где именно в этом классе вставлять html-тэги для меню (цвет, шрифт и т.д. и т.п.), и если это возможно то хотя бы с маленьким примером. Буду признателен за ответ.

  • Сергей:

    Здравствуйте, Михаил!

    Зарегестрировал меню, назначил свои стили, но вот какая проблема:
    У меня есть страница "Новости", где выводятся посты.

    При нажатии на вкладку "Новости" кнопке назначаются активные стили (становится темной), но, как только я нажимаю на ссылку поста кнопка "Новости" перестает быть активной.
    Например, на Вашем блоге кнопка "Блог" продолжает оставаться выделенной при просмотре статей. Хотелось бы реализовать похожее решение. Странно, но в интернете не получилось найти нужной информации.
    Заранее спасибо за ответ!

  • Алексей:

    здравствуйте! Подскажите пожалуйста
    Возникла необходимость одному пункту меню (контакты) задать класс Сделать это можно прописав класс в пункте меню Класс прописываю но он у меня не отображается
    в файле функции есть код добавляющий описание в меню может в нем проблема!?

    class Menu_Description extends Walker_Nav_Menu {
    	function start_el(&$output, $item, $depth, $args) {
    		global $wp_query;
    		$indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
    	       	$class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
    		$class_names = ' class="' . esc_attr( $class_names ) . '"';
        		$class_names = ( $item->current == 1 ) ? ' class="current-menu-item"' : '';
            $output .= $indent . '<li itemprop="name"' . $id . $value . $class_names .'>';
            // атрибуты элемента, title="", rel="", target="" и href=""
    		$attributes = ! empty( $item->attr_title ) ? ' title="' . esc_attr( $item->attr_title ) .'"' : '';
    		$attributes .= ! empty( $item->target ) ? ' target="' . esc_attr( $item->target ) .'"' : '';
    		$attributes .= ! empty( $item->xfn ) ? ' rel="' . esc_attr( $item->xfn ) .'"' : '';
    		$attributes .= ! empty( $item->url ) ? ' href="' . esc_attr( $item->url ) .'"' : '';
     
    		$item_output = $args->before;
    		$item_output .= '<a itemprop="url" '. $attributes .'>';
    		$item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
    		$item_output .= '<br /><span class="sub">' . $item->description . '</span>';
    		$item_output .= '</a>';
    		$item_output .= $args->after;
    		$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
    	}
    }

    Меню вывожу в шапке сайта так

    <?php $walker = new Menu_Description;?>
    <?php wp_nav_menu( array('menu' => 'Навигация по сайту','container' => 'false','items_wrap' => '<a href="#" id="pull">меню</a><ul>%3$s</ul>','walker' => $walker ));?>

    Подскажите пожалуйста как задать свой класс нужному пункту меню?

  • Руслан:

    Здравствуйте, такая проблема с которой столкнулся, нужен такой вид меню:

    <li class="active"><a href="#">Главная</a></li>
    <li class="divider-vertical"></li>
    <li><a href="#">Акция</a></li>
    <li class="divider-vertical"></li>
    <li><a href="#">Продукция</a></li>

    Т.е. после каждого пункта списка добавлять еще список пустой но с определенными классом:

    <li class="divider-vertical"></li>

    кроме последнего пункта
    Вопрос: Как узнать что это последний пункт меню и поставить в условии не выводить "

    <li class="divider-vertical"></li>

    " после конца списка?

    • Миша:

      Здравствуйте, если я правильно понял вашу задачу, почему бы вам не решить её при помощи CSS псевдоэлементов :before или :after?

      • Руслан:

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

        <li class="divider-vertical"></li>

        ставится разделитель пунктов. Ну это не столь важно данную проблему можно решить двумя способами с помощью

        https://misha.blog/blog/wordpress/wp_get_nav_menu_items.html

        или же с помощью данного Walker только в админке меню добавляем любой класс к последнему элементу и тогда мы его уже можем вычислить, пример:

        $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
         
        		if($item->classes[0]!=='last'){
        	 		$output .= '<li class="divider-vertical"></li>';
        		}

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

Оставить комментарий / вопрос

phpjsHTMLCSSSQLПросто код
  Комментарии закрыты.