wp_get_nav_menu_items

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

Возвращает все элементы (ссылки) указанного меню навигации, которое создается в панели: “внешний вид” > “меню” (Appearance > Menus).

Передав название, ID или слаг меню, функция получит элементы меню навигации.

✈ 1 раз = 0.005с = очень медленно | 50000 раз = 239с = тормоз PHP 7.0.2, WP 4.4.2
Хуки из функции:
wp_get_nav_menu_items
Возвращает

массив данных о ссылках.

Использование

wp_get_nav_menu_items( $menu, $args );

Шаблон использования

$args = array(
	'order'                  => 'ASC',
	'orderby'                => 'menu_order',
	'output'                 => ARRAY_A,
	'output_key'             => 'menu_order',
	'update_post_term_cache' => false,
);

$items = wp_get_nav_menu_items( 5, $args );
$menu(строка/объект) (обязательный)
ID меню или объект меню (термина).
Идентификатор, который задается при регистрации меню (menu location) — указывать нельзя.
По умолчанию: нет
$args(массив)
Аргументы в виде массива, которые формируют выводимые данные.
По умолчанию: по умолчанию

Примеры

#1. Пример построения простого списка меню с использованием функции wp_get_nav_menu_items():

// Получим элементы меню на основе параметра $menu_name (тоже что и 'theme_location' или 'menu' в аргументах wp_nav_menu)
// Этот код - основа функции wp_nav_menu, где получается ID меню из слага

$menu_name = 'custom_menu_slug';

if( $locations = get_nav_menu_locations() && isset($locations[ $menu_name ]) ){
	$menu = wp_get_nav_menu_object( $locations[ $menu_name ] ); // получаем ID

	$menu_items = wp_get_nav_menu_items( $menu ); // получаем элементы меню

	// создаем список
	$menu_list = '<ul id="menu-' . $menu_name . '">';

	foreach ( (array) $menu_items as $key => $menu_item ){
		$menu_list .= '<li><a href="' . $menu_item->url . '">' . $menu_item->title . '</a></li>';
	}

	$menu_list .= '</ul>';
}
else 
	$menu_list = '<ul><li>Меню "' . $menu_name . '" не определено.</li></ul>';

#2 Какие данные содержит возвращаемый объект

Не имеет значения какая ссылка добавлена в меню в админке: пост, тексономия или произвольная ссылка. Все они сохраняются в таблице wp_posts c одинаковыми полями (поля меню).

Многие из полей попросту не нужны и не имеют смысла, потому что относятся к записям. Используйте последние значения начиная с db_id они определяют пункт меню.

$items = wp_get_nav_menu_items( 654 );

print_r( $items );

/* выведет:
Array
(
	[1] => WP_Post Object
		(
// это поля поста использовать их не универсально...
			[ID] => 6364
			[post_author] => 1
			[post_date] => 2015-12-06 12:20:18
			[post_date_gmt] => 2015-12-06 07:20:18
			[post_content] => 
			[post_title] => Произвольная ссылка 2
			[post_excerpt] => 
			[post_status] => publish
			[comment_status] => closed
			[ping_status] => closed
			[post_password] => 
			[post_name] => proizvolnaya-ssylka-2
			[to_ping] => 
			[pinged] => 
			[post_modified] => 2015-12-06 12:20:18
			[post_modified_gmt] => 2015-12-06 07:20:18
			[post_content_filtered] => 
			[post_parent] => 0
			[guid] => http://wp-kama.ru/id_6364/proizvolnaya-ssylka-2.html
			[menu_order] => 4
			[post_type] => nav_menu_item
			[post_mime_type] => 
			[comment_count] => 0
			[filter] => raw
// это поля меню, используйте их
			[db_id] => 6364
			[menu_item_parent] => 0
			[object_id] => 6364
			[object] => custom
			[type] => custom
			[type_label] => Произвольная ссылка
			[title] => Произвольная ссылка 2
			[url] => http://site.ru/foo
			[target] => 
			[attr_title] => 
			[description] => 
			[classes] => Array
				(
					[0] => 
				)

			[xfn] => 
		)
	[1] => WP_Post Object
		(
		... 
		)

)

*/

Код из


wp-includes/nav-menu.php

WP 4.7.2

<?php
function wp_get_nav_menu_items( $menu, $args = array() ) {
	$menu = wp_get_nav_menu_object( $menu );

	if ( ! $menu ) {
		return false;
	}

	static $fetched = array();

	$items = get_objects_in_term( $menu->term_id, 'nav_menu' );
	if ( is_wp_error( $items ) ) {
		return false;
	}

	$defaults = array( 'order' => 'ASC', 'orderby' => 'menu_order', 'post_type' => 'nav_menu_item',
		'post_status' => 'publish', 'output' => ARRAY_A, 'output_key' => 'menu_order', 'nopaging' => true );
	$args = wp_parse_args( $args, $defaults );
	$args['include'] = $items;

	if ( ! empty( $items ) ) {
		$items = get_posts( $args );
	} else {
		$items = array();
	}

	// Get all posts and terms at once to prime the caches
	if ( empty( $fetched[$menu->term_id] ) || wp_using_ext_object_cache() ) {
		$fetched[$menu->term_id] = true;
		$posts = array();
		$terms = array();
		foreach ( $items as $item ) {
			$object_id = get_post_meta( $item->ID, '_menu_item_object_id', true );
			$object    = get_post_meta( $item->ID, '_menu_item_object',    true );
			$type      = get_post_meta( $item->ID, '_menu_item_type',      true );

			if ( 'post_type' == $type )
				$posts[$object][] = $object_id;
			elseif ( 'taxonomy' == $type)
				$terms[$object][] = $object_id;
		}

		if ( ! empty( $posts ) ) {
			foreach ( array_keys($posts) as $post_type ) {
				get_posts( array('post__in' => $posts[$post_type], 'post_type' => $post_type, 'nopaging' => true, 'update_post_term_cache' => false) );
			}
		}
		unset($posts);

		if ( ! empty( $terms ) ) {
			foreach ( array_keys($terms) as $taxonomy ) {
				get_terms( $taxonomy, array(
					'include' => $terms[ $taxonomy ],
					'hierarchical' => false,
				) );
			}
		}
		unset($terms);
	}

	$items = array_map( 'wp_setup_nav_menu_item', $items );

	if ( ! is_admin() ) { // Remove invalid items only in front end
		$items = array_filter( $items, '_is_valid_nav_menu_item' );
	}

	if ( ARRAY_A == $args['output'] ) {
		$items = wp_list_sort( $items, array(
			$args['output_key'] => 'ASC',
		) );
		$i = 1;
		foreach ( $items as $k => $item ) {
			$items[$k]->{$args['output_key']} = $i++;
		}
	}

	/**
	 * Filters the navigation menu items being returned.
	 *
	 * @since 3.0.0
	 *
	 * @param array  $items An array of menu item post objects.
	 * @param object $menu  The menu object.
	 * @param array  $args  An array of arguments used to retrieve menu item objects.
	 */
	return apply_filters( 'wp_get_nav_menu_items', $items, $menu, $args );
}