Снова ищем одного-двух вордпрессеров в нашу команду!

Как вывести дочерние пункты конкретного элемента меню?

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

Иногда проблема решалась при помощи волкера, иногда при помощи не всем известной wp_get_nav_menu_items(), но порой приходилось придумывать более изощрённые способы вывода пунктов. В ходе одного из таких способов я и использовал функцию, которую вы видите ниже.

Преимущество функции в том, что она не делает запросов в базу данных или куда-то ещё, а работает с уже предоставленным ей списком элементов, алгоритм такой:

  1. Предоставляем функции параметр $nav_menu_items — массив объектов элементов меню, который очень удобно получить при помощи wp_get_nav_menu_items().
  2. Указываем в параметрах также ID элемента, дочерние элементы которого нужно получить.
  3. Из предоставленного массива функция отбирает нужные нам элементы и возвращает их также в виде массива объектов.
/**
* Возвращает дочерние элементы пункта меню
*
* @param целое ID родительского элемента
* @param массив Массив объектов элементов меню, по которым будет проходить отбор
* @param логическое Нужно ли учитывать дочерние элементы всех уровней вложенности
* @return массив Массив объектов дочерних элементов
*/
function true_get_nav_menu_children_items( $parent_id, $nav_menu_items, $dpth = true ) {
	$dochernie = array();
	foreach ( (array) $nav_menu_items as $nav_item ) {
		if ( $nav_item->menu_item_parent == $parent_id ) {
			$dochernie[] = $nav_item;
 
			// если вам не нужны дочерние всех уровней вложенности, то даже можете удалить следующие 5 строк кода
			if ( $dpth ) {
				if ( $dch = get_nav_menu_item_children( $nav_item->ID, $nav_menu_items ) )
					$dochernie = array_merge( $dochernie, $dch );
				}
			}
		}
	}
	return $dochernie;
}

Вот по сути и всё — добавляете её в functions.php и потом где хотите используете на сайте.

Миша

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

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

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

  • Александр4 декабря 2015 #

    Миш, а ты уже глянул новый вп? Интересует разбор о тебя о встроенной поддержке адаптивных картинок.

    А про менюху полезно, хотя я для этого обычно второе регистрирую ))

    • Миша4 декабря 2015 #

      Спасибо за наводку на тему нового поста 🙂

      • Миша16 декабря 2015 #

        Пост будет готов в пятницу.

        • Александр16 декабря 2015 #

          Отлично, спасибо

  • Егор5 декабря 2015 #

    Здравствуй, Миша. Получается что дочерние элементы, например дочерние страницы будут автоматически добавляться в меню?

    • Миша5 декабря 2015 #

      Привет!
      Зависит конечно от того, что передать в параметре $nav_menu_items, а вообще — да.

  • Илья Волков5 апреля 2016 #

    Ох, уже стыдно заваливать вопросами, но приходится.

    Я пришел к выводу чтобы найти быстрее полезную инфу на truemisha надо открыть https://misha.blog/sitemap и включить поиск по всей странице (ctrl + f).

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

    Меня интересует следующий вопрос: Как отобразить в SideBar или где-либо еще на странице WP вложенные в неё же страницы.

    Пояснение: например, site.com/1/2/3/

    главной странице принадлежат дочки: 1, 2, 3
    странице "1": 2,3
    странице "2": 3.

    то есть "хлебные крошки наоборот".

    Я делал так, что отображались вообще все странички. Но как сделать так чтобы вложенность отображалась уникальная, присвоенная конкретной странице.

    Еще пример:
    есть у автомобилей марки - 60 штук,
    у каждой марки есть модели,
    а у моделей конфигурации.

    * - принцип родительских и дочерних элементов.

    получается такой расклад:
    1. стартовая страница - автомобили (где список марок)
    2. страница выбранной марки- где список моделей
    3. страница конкретной модели - где список конфигураций.

    p.s. почти пост полноценный получился))

    • Миша6 апреля 2016 #

      Зато понятно сформулирован вопрос))

      На самом деле делается это проще простого при помощи WP_Query.

      global $post; // получаем объект текущей страницы
       
      $q = new WP_Query( array( 'post_type' => 'page', 'post_parent' => $post->ID, 'posts_per_page' => -1 ) );
      • Илья Волков6 апреля 2016 #

        спасибо, попробую)

        а если надо в таком формате?:

         
        <ul>
        <li><a href="/1"><img src="миниатюра страницы 1">1</a></li>
        <li><a href="/2"><img src="миниатюра страницы 2">2</a></li>
        </ul>
        • Миша6 апреля 2016 #

          Тебе как, готовый код или ссылку на пост?)

          • Илья Волков6 апреля 2016 #

            можно пост) заранее спасибо))

          • Илья Волков6 апреля 2016 #

            я так понимаю речь идет об этом посте https://misha.blog/blog/wordpress/wp_query.html

            • Миша6 апреля 2016 #

              А если проблемы с миниатюрами, то ещё и об этом.

              • Илья Волков10 мая 2016 #

                скинь плиз код)

                • Миша10 мая 2016 #
                  <?php
                  global $post;
                   
                  $q = new WP_Query( array( 'post_type' => 'page', 'post_parent' => $post->ID, 'posts_per_page' => -1 ) );
                  echo '<ul>';
                  while( $q->have_posts() ) : $q->the_post(); ?>
                  <li><a href="<?php the_permalink() ?>"><?php the_post_thumbnail() ?><?php the_title() ?></a></li>
                  <?php endwhile;
                  echo '</ul>';
                  wp_reset_postdata();
                  • Илья Волков10 мая 2016 #

                    почему при выводе шорткода, русский контент из этого шорткода в вопросиках. Хотя стоит кодировка utf8 без BOM. Сам шорткода находится в function.php. А база в utf8-general-ci?

                  • Илья Волков11 мая 2016 #

                    ура, заработало - спасибо огромное!
                    +1 к карме

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

Если вы хотите добавить код, не забудьте обернуть его в <pre lang="php"></pre>, в случае несоблюдения этого условия в 99% случаях ваш коммент будет удалён, а автор заблокирован. Печалька.