WordPress函数wp_nav_menu()

描述:

显示前台导航菜单

用法:

<?php
    $defaults = array(
        'theme_location'  => '',
        '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>',
        'depth'           => 0,
        'walker'          => ''
    );
    wp_nav_menu( $defaults );
?>

参数:

$theme_location

(string) (可选) 用于在调用导航菜单时指定注册过的某一个导航菜单名,如果没有指定,则显示第一个。

默认值: None

$menu

(string) (可选) 使用导航菜单的名称调用菜单,可以是 id, slug, name (按顺序匹配的) 。

默认值: None

$container

(string) (可选) ul 父节点(这里指导航菜单的容器)的标签类型,只支持div 和 nav 标签, 如果是其它值, ul 父节点的标签将不会被显示。也可以用false(container => false)去掉ul父节点标签。

默认值: div

$container_class

(string) (可选) ul 父节点的 class 属性值。

默认值: menu-{menu slug}-container

$container_id

(string) (可选) ul 父节点的 id 属性值。

默认值: None

$menu_class

(string) (可选) ul 节点的 class 属性值

默认值: menu

$menu_id

(string) (可选) ul 节点的 id 属性值。

默认值: menu-{menu slug};

$echo

(boolean) (可选) 确定直接显示导航菜单还是返回 HTML 片段,如果想将导航的代码作为赋值使用,可设置为false。

默认值: true

$fallback_cb

(string) (可选) 用于没有在后台设置导航时调的回调函数。

默认值: wp_page_menu

$before

(string) (可选) 显示在每个菜单链接前的文本。

默认值: None

$after

(string) (可选) 显示在每个菜单链接后的文本。

默认值: None

$link_before

(string) (可选) 显示在每个菜单链接文本前的文本。

默认值: None

$link_after

(string) (可选) 显示在每个菜单链接文本后的文本。

默认值: None

$items_wrap

(string) (可选) 使用字符串替换修改ul的class。

默认值: <ul id=”%1$s” class=”%2$s”>%3$s</ul>

$depth

(integer) (可选) 显示菜单的层级, 当数值为 0 时显示所有层级的菜单(就是你设置几级菜单都可以显示,一般最常用的都是二级菜单)。

默认值: 0

$walker

(object) (可选) 自定义walker

默认值: new Walker_Nav_Menu

示例:

默认菜单

<div class="access">
  <?php wp_nav_menu(); ?>
</div>

特定菜单

<?php wp_nav_menu( array('menu' => 'Project Nav' )); ?>

源文件:

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
    $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 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        = array();
    $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;
    }
}