예제 #1
0
/**
 * Displays a navigation menu.
 *
 * Optional $args contents:
 *
 * menu - The menu that is desired.  Accepts (matching in order) id, slug, name. Defaults to blank.
 * menu_class - CSS class to use for the ul element which forms the menu. Defaults to 'menu'.
 * menu_id - The ID that is applied to the ul element which forms the menu. Defaults to the menu slug, incremented.
 * container - Whether to wrap the ul, and what to wrap it with. Defaults to 'div'.
 * container_class - the class that is applied to the container. Defaults to 'menu-{menu slug}-container'.
 * container_id - The ID that is applied to the container. Defaults to blank.
 * fallback_cb - If the menu doesn't exists, a callback function will fire. Defaults to 'nxt_page_menu'. Set to false for no fallback.
 * before - Text before the link text.
 * after - Text after the link text.
 * link_before - Text before the link.
 * link_after - Text after the link.
 * echo - Whether to echo the menu or return it. Defaults to echo.
 * depth - how many levels of the hierarchy are to be included.  0 means all.  Defaults to 0.
 * walker - allows a custom walker to be specified.
 * theme_location - the location in the theme to be used.  Must be registered with register_nav_menu() in order to be selectable by the user.
 * items_wrap - How the list items should be wrapped. Defaults to a ul with an id and class. Uses printf() format with numbered placeholders.
 *
 * @since 3.0.0
 *
 * @param array $args Arguments
 */
function nxt_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' => 'nxt_page_menu', 'before' => '', 'after' => '', 'link_before' => '', 'link_after' => '', 'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s</ul>', 'depth' => 0, 'walker' => '', 'theme_location' => '');
    $args = nxt_parse_args($args, $defaults);
    $args = apply_filters('nxt_nav_menu_args', $args);
    $args = (object) $args;
    // Get the nav menu based on the requested menu
    $menu = nxt_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 = nxt_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 = nxt_get_nav_menus();
        foreach ($menus as $menu_maybe) {
            if ($menu_items = nxt_get_nav_menu_items($menu_maybe->term_id)) {
                $menu = $menu_maybe;
                break;
            }
        }
    }
    // If the menu exists, get its items.
    if ($menu && !is_nxt_error($menu) && !isset($menu_items)) {
        $menu_items = nxt_get_nav_menu_items($menu->term_id);
    }
    // If no menu was found or if the menu has no items and no location was requested, call the fallback_cb if it exists
    if ((!$menu || is_nxt_error($menu) || isset($menu_items) && empty($menu_items) && !$args->theme_location) && $args->fallback_cb && is_callable($args->fallback_cb)) {
        return call_user_func($args->fallback_cb, (array) $args);
    }
    // If no fallback function was specified and the menu doesn't exists, bail.
    if (!$menu || is_nxt_error($menu)) {
        return false;
    }
    $nav_menu = $items = '';
    $show_container = false;
    if ($args->container) {
        $allowed_tags = apply_filters('nxt_nav_menu_container_allowedtags', array('div', 'nav'));
        if (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
    _nxt_menu_item_classes_by_context($menu_items);
    $sorted_menu_items = array();
    foreach ((array) $menu_items as $key => $menu_item) {
        $sorted_menu_items[$menu_item->menu_order] = $menu_item;
    }
    unset($menu_items);
    $sorted_menu_items = apply_filters('nxt_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 : '';
    // Allow plugins to hook into the menu to add their own <li>'s
    $items = apply_filters('nxt_nav_menu_items', $items, $args);
    $items = apply_filters("nxt_nav_menu_{$menu->slug}_items", $items, $args);
    $nav_menu .= sprintf($args->items_wrap, esc_attr($wrap_id), esc_attr($wrap_class), $items);
    unset($items);
    if ($show_container) {
        $nav_menu .= '</' . $args->container . '>';
    }
    $nav_menu = apply_filters('nxt_nav_menu', $nav_menu, $args);
    if ($args->echo) {
        echo $nav_menu;
    } else {
        return $nav_menu;
    }
}
예제 #2
0
 function widget($args, $instance)
 {
     // Get menu
     $nav_menu = !empty($instance['nav_menu']) ? nxt_get_nav_menu_object($instance['nav_menu']) : false;
     if (!$nav_menu) {
         return;
     }
     $instance['title'] = apply_filters('widget_title', empty($instance['title']) ? '' : $instance['title'], $instance, $this->id_base);
     echo $args['before_widget'];
     if (!empty($instance['title'])) {
         echo $args['before_title'] . $instance['title'] . $args['after_title'];
     }
     nxt_nav_menu(array('fallback_cb' => '', 'menu' => $nav_menu));
     echo $args['after_widget'];
 }
예제 #3
0
/**
 * Returns all menu items of a navigation menu.
 *
 * @since 3.0.0
 *
 * @param string $menu menu name, id, or slug
 * @param string $args
 * @return mixed $items array of menu items, else false.
 */
function nxt_get_nav_menu_items($menu, $args = array())
{
    global $_nxt_using_ext_object_cache;
    $menu = nxt_get_nav_menu_object($menu);
    if (!$menu) {
        return false;
    }
    static $fetched = array();
    $items = get_objects_in_term($menu->term_id, 'nav_menu');
    if (empty($items)) {
        return $items;
    }
    $defaults = array('order' => 'ASC', 'orderby' => 'menu_order', 'post_type' => 'nav_menu_item', 'post_status' => 'publish', 'output' => ARRAY_A, 'output_key' => 'menu_order', 'nopaging' => true, 'update_post_term_cache' => false);
    $args = nxt_parse_args($args, $defaults);
    if (count($items) > 1) {
        $args['include'] = implode(',', $items);
    } else {
        $args['include'] = $items[0];
    }
    $items = get_posts($args);
    if (is_nxt_error($items) || !is_array($items)) {
        return false;
    }
    // Get all posts and terms at once to prime the caches
    if (empty($fetched[$menu->term_id]) || $_nxt_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]));
            }
        }
        unset($terms);
    }
    $items = array_map('nxt_setup_nav_menu_item', $items);
    if (!is_admin()) {
        // Remove invalid items only in frontend
        $items = array_filter($items, '_is_valid_nav_menu_item');
    }
    if (ARRAY_A == $args['output']) {
        $GLOBALS['_menu_item_sort_prop'] = $args['output_key'];
        usort($items, '_sort_nav_menu_items');
        $i = 1;
        foreach ($items as $k => $item) {
            $items[$k]->{$args}['output_key'] = $i++;
        }
    }
    return apply_filters('nxt_get_nav_menu_items', $items, $menu, $args);
}
예제 #4
0
if (!$recently_edited && is_nav_menu($nav_menu_selected_id)) {
    $recently_edited = $nav_menu_selected_id;
    // Else if $nav_menu_selected_id is not a menu and not requesting that we create a new menu, but $recently_edited is a menu, grab that one.
} elseif (0 == $nav_menu_selected_id && !isset($_REQUEST['menu']) && is_nav_menu($recently_edited)) {
    $nav_menu_selected_id = $recently_edited;
    // Else try to grab the first menu from the menus list
} elseif (0 == $nav_menu_selected_id && !isset($_REQUEST['menu']) && !empty($nav_menus)) {
    $nav_menu_selected_id = $nav_menus[0]->term_id;
}
// Update the user's setting
if ($nav_menu_selected_id != $recently_edited && is_nav_menu($nav_menu_selected_id)) {
    update_user_meta($current_user->ID, 'nav_menu_recently_edited', $nav_menu_selected_id);
}
// If there's a menu, get its name.
if (!$nav_menu_selected_title && is_nav_menu($nav_menu_selected_id)) {
    $_menu_object = nxt_get_nav_menu_object($nav_menu_selected_id);
    $nav_menu_selected_title = !is_nxt_error($_menu_object) ? $_menu_object->name : '';
}
// Generate truncated menu names
foreach ((array) $nav_menus as $key => $_nav_menu) {
    $_nav_menu->truncated_name = trim(nxt_html_excerpt($_nav_menu->name, 40));
    if ($_nav_menu->truncated_name != $_nav_menu->name) {
        $_nav_menu->truncated_name .= '&hellip;';
    }
    $nav_menus[$key]->truncated_name = $_nav_menu->truncated_name;
}
// Ensure the user will be able to scroll horizontally
// by adding a class for the max menu depth.
global $_nxt_nav_menu_max_depth;
$_nxt_nav_menu_max_depth = 0;
// Calling nxt_get_nav_menu_to_edit generates $_nxt_nav_menu_max_depth
예제 #5
0
/**
 * Returns the menu formatted to edit.
 *
 * @since 3.0.0
 *
 * @param string $menu_id The ID of the menu to format.
 * @return string|nxt_Error $output The menu formatted to edit or error object on failure.
 */
function nxt_get_nav_menu_to_edit($menu_id = 0)
{
    $menu = nxt_get_nav_menu_object($menu_id);
    // If the menu exists, get its items.
    if (is_nav_menu($menu)) {
        $menu_items = nxt_get_nav_menu_items($menu->term_id, array('post_status' => 'any'));
        $result = '<div id="menu-instructions" class="post-body-plain';
        $result .= !empty($menu_items) ? ' menu-instructions-inactive">' : '">';
        $result .= '<p>' . __('Select menu items (pages, categories, links) from the boxes at left to begin building your custom menu.') . '</p>';
        $result .= '</div>';
        if (empty($menu_items)) {
            return $result . ' <ul class="menu" id="menu-to-edit"> </ul>';
        }
        $walker_class_name = apply_filters('nxt_edit_nav_menu_walker', 'Walker_Nav_Menu_Edit', $menu_id);
        if (class_exists($walker_class_name)) {
            $walker = new $walker_class_name();
        } else {
            return new nxt_Error('menu_walker_not_exist', sprintf(__('The Walker class named <strong>%s</strong> does not exist.'), $walker_class_name));
        }
        $some_pending_menu_items = $some_invalid_menu_items = false;
        foreach ((array) $menu_items as $menu_item) {
            if (isset($menu_item->post_status) && 'draft' == $menu_item->post_status) {
                $some_pending_menu_items = true;
            }
            if (!empty($menu_item->_invalid)) {
                $some_invalid_menu_items = true;
            }
        }
        if ($some_pending_menu_items) {
            $result .= '<div class="updated inline"><p>' . __('Click Save Menu to make pending menu items public.') . '</p></div>';
        }
        if ($some_invalid_menu_items) {
            $result .= '<div class="error inline"><p>' . __('There are some invalid menu items. Please check or delete them.') . '</p></div>';
        }
        $result .= '<ul class="menu" id="menu-to-edit"> ';
        $result .= walk_nav_menu_tree(array_map('nxt_setup_nav_menu_item', $menu_items), 0, (object) array('walker' => $walker));
        $result .= ' </ul> ';
        return $result;
    } elseif (is_nxt_error($menu)) {
        return $menu;
    }
}