Parameters
$args array optional Array of nav menu arguments.
menu int|string| WP_Term Desired menu. Accepts a menu ID, slug, name, or object.
menu_class string CSS class to use for the ul element which forms the menu.
Default 'menu' . menu_id string The ID that is applied to the ul element which forms the menu.
Default is the menu slug, incremented. container string Whether to wrap the ul, and what to wrap it with.
Default 'div' . container_class string Class that is applied to the container.
Default ‘menu-{menu slug}-container’. container_id string The ID that is applied to the container. container_aria_label string The aria-label attribute that is applied to the container when it’s a nav element. fallback_cb callable|false If the menu doesn’t exist, a callback function will fire.
Default is 'wp_page_menu' . Set to false for no fallback. before string Text before the link markup. after string Text after the link markup. link_before string Text before the link text. link_after string Text after the link text. echo bool Whether to echo the menu or return it. Default true. depth int How many levels of the hierarchy are to be included.
0 means all. Default 0.
Default 0. walker object Instance of a custom walker class. theme_location string Theme location to be used. Must be registered with register_nav_menu() in order to be selectable by the user. items_wrap string How the list items should be wrapped. Uses printf() format with numbered placeholders. Default is a ul with an id and class. item_spacing string Whether to preserve whitespace within the menu’s HTML.
Accepts 'preserve' or 'discard' . Default 'preserve' .
Default: array()
Source
function wp_nav_menu( $args = array() ) { static $menu_id_slugs = array(); $defaults = array( 'menu' => '', 'container' => 'div', 'container_class' => '', 'container_id' => '', 'container_aria_label' => '', 'menu_class' => 'menu', 'menu_id' => '', 'echo' => true, 'fallback_cb' => 'wp_page_menu', 'before' => '', 'after' => '', 'link_before' => '', 'link_after' => '', 'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s</ul>', 'item_spacing' => 'preserve', 'depth' => 0, 'walker' => '', 'theme_location' => '', ); $args = wp_parse_args( $args, $defaults ); if ( ! in_array( $args['item_spacing'], array( 'preserve', 'discard' ), true ) ) { // Invalid value, fall back to default. $args['item_spacing'] = $defaults['item_spacing']; } /** * Filters the arguments used to display a navigation menu. * * @since 3.0.0 * * @see wp_nav_menu() * * @param array $args Array of wp_nav_menu() arguments. */ $args = apply_filters( 'wp_nav_menu_args', $args ); $args = (object) $args; /** * Filters whether to short-circuit the wp_nav_menu() output. * * Returning a non-null value from the filter will short-circuit wp_nav_menu(), * echoing that value if $args->echo is true, returning that value otherwise. * * @since 3.9.0 * * @see wp_nav_menu() * * @param string|null $output Nav menu output to short-circuit with. Default null. * @param stdClass $args An object containing wp_nav_menu() arguments. */ $nav_menu = apply_filters( 'pre_wp_nav_menu', null, $args ); if ( null !== $ nav_menu ) { if ( $args->echo ) { echo $nav_menu; return; } return $nav_menu; } // Get the nav menu based on the requested menu. $menu = wp_get_nav_menu_object( $args->menu ); // Get the nav menu based on the theme_location. $locations = get_nav_menu_locations(); if ( ! $ menu && $args->theme_location && $locations && isset( $locations[ $args->theme_location ] ) ) { $menu = wp_get_nav_menu_object( $locations[ $args->theme_location ] ); } // Get the first menu that has items if we still can't find a menu. if ( ! $ menu && ! $args->theme_location ) { $menus = wp_get_nav_menus(); foreach ( $menus as $menu_maybe ) { $menu_items = wp_get_nav_menu_items( $menu_maybe->term_id, array( 'update_post_term_cache' => false ) ); if ( $menu_items ) { $menu = $menu_maybe; break; } } } if ( empty( $args->menu ) ) { $args->menu = $menu; } // If the menu exists, get its items. if ( $menu && ! is_wp_error( $menu ) && ! isset( $menu_items ) ) { $menu_items = wp_get_nav_menu_items( $menu->term_id, array( 'update_post_term_cache' => false ) ); } /* * If no menu was found: * - Fall back (if one was specified), or bail. * * If no menu items were found: * - Fall back, but only if no theme location was specified. * - Otherwise, bail. */ if ( ( ! $menu || is_wp_error( $menu ) || ( isset( $menu_items ) && empty( $menu_items ) && ! $ args->theme_location ) ) && isset( $args->fallback_cb ) && $args->fallback_cb && is_callable( $args->fallback_cb ) ) { return call_user_func( $args->fallback_cb, (array) $args ); } if ( ! $ menu || is_wp_error( $menu ) ) { return false; } $nav_menu = ''; $items = ''; $show_container = false; if ( $args->container ) { /** * Filters the list of HTML tags that are valid for use as menu containers. * * @since 3.0.0 * * @param string[] $tags The acceptable HTML tags for use as menu containers. * Default is array containing 'div' and 'nav'. */ $allowed_tags = apply_filters( 'wp_nav_menu_container_allowedtags', array( 'div', 'nav' ) ); if ( is_string( $args->container ) && in_array( $args->container, $allowed_tags, true ) ) { $show_container = true; $class = $args->container_class ? ' class="' . esc_attr( $args->container_class ) . ' "' : ' class="menu-' . $ menu->slug . '-container"'; $id = $args->container_id ? ' id="' . esc_attr( $args->container_id ) . ' "' : ''; $aria_label = ( 'nav' === $args->container && $args->container_aria_label ) ? ' aria-label="' . esc_attr( $args->container_aria_label ) . ' "' : ''; $nav_menu .= '<' . $ args->container . $id . $class . $aria_label . '>'; } } // Set up the $menu_item variables. _wp_menu_item_classes_by_context( $menu_items ); $sorted_menu_items = array(); $menu_items_with_children = array(); foreach ( (array) $menu_items as $menu_item ) { /* * Fix invalid `menu_item_parent`. See: https://core.trac.wordpress.org/ticket/56926. * Compare as strings. Plugins may change the ID to a string. */ if ( (string) $menu_item->ID === (string) $menu_item->menu_item_parent ) { $menu_item->menu_item_parent = 0; } $sorted_menu_items[ $menu_item->menu_order ] = $menu_item; if ( $menu_item->menu_item_parent ) { $menu_items_with_children[ $menu_item->menu_item_parent ] = true; } } // Add the menu-item-has-children class where applicable. if ( $menu_items_with_children ) { foreach ( $sorted_menu_items as &$menu_item ) { if ( isset( $menu_items_with_children[ $menu_item->ID ] ) ) { $menu_item->classes[] = 'menu-item-has-children'; } } } unset( $menu_items, $menu_item ); /** * Filters the sorted list of menu item objects before generating the menu's HTML. * * @since 3.1.0 * * @param array $sorted_menu_items The menu items, sorted by each menu item's menu order. * @param stdClass $args An object containing wp_nav_menu() arguments. */ $sorted_menu_items = apply_filters( 'wp_nav_menu_objects', $sorted_menu_items, $args ); $items .= walk_nav_menu_tree( $sorted_menu_items, $args->depth, $args ); unset( $sorted_menu_items ); // Attributes. if ( ! empty( $args->menu_id ) ) { $wrap_id = $args->menu_id; } else { $wrap_id = 'menu-' . $ menu->slug; while ( in_array( $wrap_id, $menu_id_slugs, true ) ) { if ( preg_match( '#-(\d+)$#', $wrap_id, $matches ) ) { $wrap_id = preg_replace( '#-(\d+)$#', '-' . ++$ matches[1], $wrap_id ); } else { $wrap_id = $wrap_id . '- 1'; } } } $menu_id_slugs[] = $wrap_id; $wrap_class = $args->menu_class ? $ args->menu_class : ''; /** * Filters the HTML list content for navigation menus. * * @since 3.0.0 * * @see wp_nav_menu() * * @param string $items The HTML list content for the menu items. * @param stdClass $args An object containing wp_nav_menu() arguments. */ $items = apply_filters( 'wp_nav_menu_items', $items, $args ); /** * Filters the HTML list content for a specific navigation menu. * * @since 3.0.0 * * @see wp_nav_menu() * * @param string $items The HTML list content for the menu items. * @param stdClass $args An object containing wp_nav_menu() arguments. */ $items = apply_filters( "wp_nav_menu_{$menu->slug}_items", $items, $args ); // Don't print any markup if there are no items at this point. if ( empty( $items ) ) { return false; } $nav_menu .= sprintf( $args->items_wrap, esc_attr( $wrap_id ), esc_attr( $wrap_class ), $items ); unset( $items ); if ( $show_container ) { $nav_menu .= '</' . $ args->container . '>'; } /** * Filters the HTML content for navigation menus. * * @since 3.0.0 * * @see wp_nav_menu() * * @param string $nav_menu The HTML content for the navigation menu. * @param stdClass $args An object containing wp_nav_menu() arguments. */ $nav_menu = apply_filters( 'wp_nav_menu', $nav_menu, $args ); if ( $args->echo ) { echo $nav_menu; } else { return $nav_menu; } }
Hooks
-
apply_filters ( ‘pre_wp_nav_menu’, string|null $output , stdClass $args ) Filters whether to short-circuit the wp_nav_menu() output. -
apply_filters ( ‘wp_nav_menu’, string $nav_menu , stdClass $args ) Filters the HTML content for navigation menus. -
apply_filters ( ‘wp_nav_menu_args’, array $args ) Filters the arguments used to display a navigation menu. -
apply_filters ( ‘wp_nav_menu_container_allowedtags’, string[] $tags ) Filters the list of HTML tags that are valid for use as menu containers. -
apply_filters ( ‘wp_nav_menu_items’, string $items , stdClass $args ) Filters the HTML list content for navigation menus. -
apply_filters ( ‘wp_nav_menu_objects’, array $sorted_menu_items , stdClass $args ) Filters the sorted list of menu item objects before generating the menu’s HTML. -
apply_filters ( “wp_nav_menu_{$menu->slug}_items”, string $items , stdClass $args ) Filters the HTML list content for a specific navigation menu.
Changelog
User Contributed Notes
-
Skip to note 26 content You must log in to vote on the helpfulness of this note Vote results for this note: forty-five You must log in to vote on the helpfulness of this note -
Skip to note 27 content You must log in to vote on the helpfulness of this note Vote results for this note: forty-four You must log in to vote on the helpfulness of this note -
Skip to note 28 content You must log in to vote on the helpfulness of this note Vote results for this note: twenty-six You must log in to vote on the helpfulness of this note -
Skip to note 29 content You must log in to vote on the helpfulness of this note Vote results for this note: twenty-four You must log in to vote on the helpfulness of this note -
Skip to note 30 content You must log in to vote on the helpfulness of this note Vote results for this note: eleven You must log in to vote on the helpfulness of this note -
Skip to note 31 content You must log in to vote on the helpfulness of this note Vote results for this note: eight You must log in to vote on the helpfulness of this note -
Skip to note 32 content You must log in to vote on the helpfulness of this note Vote results for this note: seven You must log in to vote on the helpfulness of this note -
Skip to note 33 content You must log in to vote on the helpfulness of this note Vote results for this note: four You must log in to vote on the helpfulness of this note -
Skip to note 34 content You must log in to vote on the helpfulness of this note Vote results for this note: four You must log in to vote on the helpfulness of this note -
Skip to note 35 content You must log in to vote on the helpfulness of this note Vote results for this note: four You must log in to vote on the helpfulness of this note -
Skip to note 36 content You must log in to vote on the helpfulness of this note Vote results for this note: three You must log in to vote on the helpfulness of this note -
Skip to note 37 content You must log in to vote on the helpfulness of this note Vote results for this note: three You must log in to vote on the helpfulness of this note -
Skip to note 38 content You must log in to vote on the helpfulness of this note Vote results for this note: three You must log in to vote on the helpfulness of this note -
Skip to note 39 content You must log in to vote on the helpfulness of this note Vote results for this note: two You must log in to vote on the helpfulness of this note -
Skip to note 40 content You must log in to vote on the helpfulness of this note Vote results for this note: two You must log in to vote on the helpfulness of this note -
Skip to note 41 content You must log in to vote on the helpfulness of this note Vote results for this note: one You must log in to vote on the helpfulness of this note -
Skip to note 42 content You must log in to vote on the helpfulness of this note Vote results for this note: one You must log in to vote on the helpfulness of this note -
Skip to note 43 content You must log in to vote on the helpfulness of this note Vote results for this note: zero You must log in to vote on the helpfulness of this note -
Skip to note 44 content You must log in to vote on the helpfulness of this note Vote results for this note: zero You must log in to vote on the helpfulness of this note -
Skip to note 45 content You must log in to vote on the helpfulness of this note Vote results for this note: zero You must log in to vote on the helpfulness of this note -
Skip to note 46 content You must log in to vote on the helpfulness of this note Vote results for this note: zero You must log in to vote on the helpfulness of this note -
Skip to note 47 content You must log in to vote on the helpfulness of this note Vote results for this note: zero You must log in to vote on the helpfulness of this note -
Skip to note 48 content You must log in to vote on the helpfulness of this note Vote results for this note: -1 You must log in to vote on the helpfulness of this note -
Skip to note 49 content You must log in to vote on the helpfulness of this note Vote results for this note: -3 You must log in to vote on the helpfulness of this note -
Skip to note 50 content You must log in to vote on the helpfulness of this note Vote results for this note: -15 You must log in to vote on the helpfulness of this note