wp_nav_menu()

目录

    之前提到的 register_nav_menus() 函数用于注册一个自定义菜单,而今天提到的 wp_nav_menu() 则是用来获取并显示我们的自定义菜单的。

    该函数的语法为:

    wp_nav_menu( array $args = array() )

    $args:数组(选填)。你要获取并显示的一个自定义菜单,包含各类参数。

    • menu:整型、字符串或者WP项目。希望调取的菜单,可以是一个 ID 、slug 、菜单名或者对象,优先于 theme_location。
    • menu_class:字符串。应用于菜单 ul 标签的 CSS 类元素。默认为“menu”。
    • menu_id:字符串。应用于菜单 ul 标签的 ID 属性。默认为菜单的 slug 。
    • container:字符串。包裹在 ul 标签外部的 HTML 标签。默认为 div 。
    • container_class:字符串。包裹在 ul标签外部 的 HTML 标签的 CSS 类元素。默认为“menu-{menu slug}-container”。
    • container_id:字符串。包裹在 ul标签外部 的 HTML 标签的 ID 属性。
    • fallback_cb:回调函数或布尔值。无回调函数时可设置为 false 。默认为 wp_page_menu 。
    • before:字符串。标签前的文本内容。
    • after:字符串。标签后的文本内容。
    • link_before:字符串,链接文本前的文本内容。
    • link_after:字符串,链接文本后的文本内容。
    • echo:布尔值。是否输出菜单并返回。默认为 true 。
    • depth:整型。显示几级菜单。 0 代表全部显示。默认是 0 。
    • walker:对象。自定义walker类的实例。
    • theme_location:字符串。显示指定菜单位置的导航。 即 register_nav_menu() 中注册时使用的 key 值,后台指定该位置使用哪个菜单,WordPress 将会自动调用对应的菜单显示,比 menu 定义更方便,优先级小于 menu。
    • items_wrap:字符串。如何包装列表项。 默认值是带有id和class的ul。 使用带编号占位符的 printf() 格式。
    • item_spacing:字符串。是否在菜单的HTML中保留空格。 接受’保留’或’丢弃’。 默认’保留’。

    该函数定义在 wp-includes/nav-menu-template.php 文件中,具体代码如下:

    function wp_nav_menu( $args = array() ) {
        static $menu_id_slugs = array();
        $defaults = array(
    	\'menu\'            => \'\',
    	\'container\'       => \'div\',
    	\'container_class\' => \'\',
    	\'container_id\'    => \'\',
    	\'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 to 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
        if ( ! $menu && $args->theme_location && ( $locations = get_nav_menu_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 ) {
    	    if ( $menu_items = wp_get_nav_menu_items( $menu_maybe->term_id, array( \'update_post_term_cache\' => false ) ) ) {
    		$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 array $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 ) ) {
    	    $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 ) . \'\"\' : \'\';
    	    $nav_menu      .= \'<\' . $args->container . $id . $class . \'>\';
            }
        }
        // Set up the $menu_item variables
        _wp_menu_item_classes_by_context( $menu_items );
        $sorted_menu_items = $menu_items_with_children = array();
        foreach ( (array) $menu_items as $menu_item ) {
    	$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 ) ) {
    	    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;
        }
    }

    参考文章:https://developer.wordpress.org/reference/functions/wp_nav_menu/

    0 条回复 A文章作者 M管理员
      暂无讨论,说说你的看法吧
    个人中心
    购物车
    优惠劵
    今日签到
    有新私信 私信列表
    搜索