WordPress.org

Make WordPress Core


Ignore:
Timestamp:
03/15/2010 04:26:46 PM (12 years ago)
Author:
ryan
Message:

Menus rework. Props ptahdunbar. see #11817

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/nav-menu-template.php

    r13694 r13704  
    2424 */
    2525function wp_nav_menu( $args = array() ) {
    26     $defaults = array( 'menu' => '', 'menu_class' => 'menu', 'format' => 'div', 'echo' => true,
    27     'fallback_cb' => 'wp_page_menu', 'link_before' => '', 'link_after' => '', 'before_link' => '', 'after_link' => '', );
     26    $defaults = array( 'menu' => '', 'container' => 'div', 'container_class' => '', 'menu_class' => 'menu', 'echo' => true,
     27    'fallback_cb' => 'wp_page_menu', 'before_link' => '', 'after_link' => '', 'before_title' => '', 'after_title' => '', );
    2828   
    2929    $args = wp_parse_args( $args, $defaults );
     
    4646    }
    4747
    48     if ( $menu )
     48    if ( !is_wp_error($menu) )
    4949        $args->menu = $menu->term_id;
    5050    $nav_menu = '';
    5151
    52     if ( 'div' == $args->format ) {
    53         if ( $menu )
    54             $nav_menu .= '<div id="menu-' . $menu->slug . '" class="' . esc_attr($args->menu_class) . '">';
    55         else
    56             $nav_menu .= '<div id="menu-default">';
     52    if ( 'div' == $args->container ) {
     53        $class = $args->container_class ? ' class="' . esc_attr($args->container_class) . '"' : '';
     54       
     55        if ( is_nav_menu($menu) ) {
     56            $nav_menu .= '<div id="menu-' . $menu->slug . '"'. $class .'>';
     57        } else {
     58            $nav_menu .= '<div'. $class .'>';
     59        }
    5760    }
    5861
    5962    $nav_menu .= wp_get_nav_menu( $args );
    6063
    61     if ( 'div' == $args->format )
     64    if ( 'div' == $args->container )
    6265        $nav_menu .= '</div>';
    63 
    64     $nav_menu = apply_filters( 'wp_nav_menu', $nav_menu );
     66   
     67    $nav_menu = apply_filters( 'wp_nav_menu', $nav_menu, $args );
    6568
    6669    if ( $args->echo )
     
    8184 **/
    8285function wp_get_nav_menu( $args = array() ) {
    83     $defaults = array( 'menu' => '', 'menu_class' => 'menu', 'ul_class' => '', 'format' => 'div', 'type' => 'frontend',
    84     'fallback_cb' => '', 'link_before' => '', 'link_after' => '', 'before_link' => '', 'after_link' => '', );
     86    $defaults = array( 'menu' => '', 'menu_class' => 'menu', 'context' => 'frontend',
     87    'fallback_cb' => '', 'before_link' => '', 'after_link' => '', 'before_title' => '', 'after_title' => '', );
    8588   
    8689    $args = wp_parse_args( $args, $defaults );
     
    8891    $args = (object) $args;
    8992   
     93    // Variable setup
     94    $nav_menu = '';
     95    $items = '';
     96    $current_parent = 0;
     97    $parent_stack = array();
     98    $parent_menu_order = array();
     99   
     100    // Get the menu object
    90101    $menu = wp_get_nav_menu_object( $args->menu );
    91102   
    92     // If no menu was found, call the fallback_cb
    93     if ( !$menu || is_wp_error($menu) ) {
     103    // If the menu exists, get it's items.
     104    if ( $menu && !is_wp_error($menu) )
     105        $menu_items = wp_get_nav_menu_items( $menu->term_id, 'backend' );
     106   
     107    // If no menu was found or if the menu has no items, call the fallback_cb
     108    if ( !$menu || is_wp_error($menu) || ( isset($menu_items) && empty($menu_items) ) ) {
    94109        if ( function_exists($args->fallback_cb) ) {
    95110            $_args = array_merge( (array)$args, array('echo' => false) );
     
    98113    }
    99114   
    100     $menu_items = wp_get_nav_menu_items( $menu->term_id );
    101     $nav_menu = '';
    102     $parent_stack = array();
    103     $current_parent = 0;
    104     $parent_menu_order = array();
    105    
    106     // Setup parentage
    107     foreach ( $menu_items as $menu_item )
    108         $parent_menu_order[ $menu_item->ID ] = $menu_item->menu_order;
    109    
    110     $ul_class = isset($args->ul_class) ? ' class="'. $args->ul_class .'"' : '';
    111     $nav_menu .= '<ul'. $ul_class .'>';
    112    
    113     // Display Loop
    114     foreach ( $menu_items as $key => $menu_item ) :
     115    foreach ( $menu_items as $key => $menu_item ) {
    115116        // Setup the $menu_item variables
    116         $menu_item = wp_setup_nav_menu_item( $menu_item );
    117 
    118         $maybe_value = 'frontend' == $args->type ? '' : ' value="'. $menu_item->ID .'"';
    119         $classes = 'frontend' == $args->type ? ' class="menu-item-'. $menu_item->type . $menu_item->li_class .'"' : '';
    120 
    121         $nav_menu .= '<li id="menu-item-'. $menu_item->ID .'"'. $maybe_value . $classes .'>';
    122         $nav_menu .= wp_get_nav_menu_item( $menu_item, $args->type, $args );
     117        $menu_item = wp_setup_nav_menu_item( $menu_item, 'frontend' );
     118
     119        $type = sanitize_title_with_dashes( $menu_item->append );
     120        $maybe_value = 'frontend' == $args->context ? '' : ' value="'. $menu_item->ID .'"';
     121        $classes = 'frontend' == $args->context ? ' class="menu-item-type-'. $type . $menu_item->li_class .'"' : '';
     122       
     123        $items .= '<li id="menu-item-'. $menu_item->ID .'"'. $maybe_value . $classes .'>';
     124        $items .= wp_get_nav_menu_item( $menu_item, $args->context, $args );
    123125       
    124126        // Indent children
    125127        $last_item = ( count( $menu_items ) == $menu_item->menu_order );
    126         if ( $last_item || $current_parent != $menu_items[ $key + 1 ]->post_parent ) {
    127             if ( $last_item || in_array( $menu_items[ $key + 1 ]->post_parent, $parent_stack ) ) {
    128                 $nav_menu .= '</li>';
    129                 while ( !empty( $parent_stack ) && ($last_item || $menu_items[ $key + 1 ]->post_parent != $current_parent ) ) {
    130                     $nav_menu .= '</ul></li>';
     128        if ( $last_item || $current_parent != $menu_items[$key + 1]->post_parent ) {
     129            if ( $last_item || in_array( $menu_items[$key + 1]->post_parent, $parent_stack ) ) {
     130                $items .= '</li>';
     131                while ( !empty( $parent_stack ) && ($last_item || $menu_items[$key + 1]->post_parent != $current_parent ) ) {
     132                    $items .= '</ul></li>';
    131133                    $current_parent = array_pop( $parent_stack );
    132134                }
     
    134136                array_push( $parent_stack, $current_parent );
    135137                $current_parent = $menu_item->ID;
    136                 $nav_menu .= '<ul>';
     138                $items .= '<ul class="sub-menu">';
    137139            }
    138140        } else {
    139             $nav_menu .= '</li>';
    140         }
    141 
    142     endforeach;
     141            $items .= '</li>';
     142        }
     143    }
     144   
     145    // CSS class
     146    $ul_class = $args->menu_class ? ' class="'. $args->menu_class .'"' : '';
     147    $nav_menu .= '<ul'. $ul_class .'>';
     148   
     149    // Allow plugins to hook into the menu to add their own <li>'s
     150    if ( 'frontend' == $args->context ) {
     151        $items = apply_filters( 'wp_nav_menu_items', $items, $args );
     152        $items = apply_filters( "wp_nav_menu_{$menu->slug}_items", $items, $args );
     153        $nav_menu .= $items;
     154    } else {
     155        $nav_menu .= $items;
     156    }
    143157   
    144158    $nav_menu .= '</ul>';
     
    148162
    149163/**
    150  * Returns a menu item.
     164 * Returns the menu item formatted based on it's context.
    151165 *
    152166 * @since 3.0.0
    153167 *
    154  * @param object $menu_item The menu item
    155  * @param string $context frontend|backend|default
    156  * @param array $args See wp_get_nav_menu().
    157  **/
    158 function wp_get_nav_menu_item( $menu_item, $context, $args = array() ) {
    159     $item = '';
     168 * @param string $menu_item The menu item to format.
     169 * @param string $context The context to which the menu item will be formatted to.
     170 * @param string $args Optional. Args used for the 'template' context.
     171 * @return string $output The menu formatted menu item.
     172 */
     173function wp_get_nav_menu_item( $menu_item, $context = 'frontend', $args = array() ) {
     174    $output = '';
    160175    switch ( $context ) {
    161176        case 'frontend':
    162             $attr_title = ( isset($menu_item->anchor_title) && '' != $menu_item->anchor_title ) ? ' title="'. esc_attr($menu_item->anchor_title) .'"' : '';
    163             $href = isset($menu_item->link) ? ' href="'. esc_url($menu_item->link) .'"' : '';
    164            
    165             $item .= '<a'. $attr_title . $href . $menu_item->target .'>';
    166             $item .= $args->before_link . esc_html( $menu_item->title ) . $args->after_link;
    167             $item .= '</a>';
     177            $attributes  = ( isset($menu_item->anchor_title) && '' != $menu_item->anchor_title ) ? ' title="'. esc_attr($menu_item->anchor_title) .'"' : '';
     178            $attributes .= ( isset($menu_item->target) && '' != $menu_item->target ) ? ' target="'. esc_attr($menu_item->target) .'"' : '';
     179            $attributes .= ( isset($menu_item->classes) && '' != $menu_item->classes ) ? ' class="'. esc_attr($menu_item->classes) .'"' : '';
     180            $attributes .= ( isset($menu_item->xfn) && '' != $menu_item->xfn ) ? ' rel="'. esc_attr($menu_item->xfn) .'"' : '';
     181            $attributes .= ( isset($menu_item->url) && '' != $menu_item->url ) ? ' href="'. esc_attr($menu_item->url) .'"' : '';
     182           
     183            $output .= esc_html( $args->before_link );
     184            $output .= '<a'. $attributes .'>';
     185            $output .= esc_html( $args->before_title . $menu_item->title . $args->after_title );
     186            $output .= '</a>';
     187            $output .= esc_html( $args->after_link );
    168188           
    169189            break;
    170190       
    171191        case 'backend':
    172             $item .= '<dl><dt>';
    173             $item .= '<span class="item-title">'. esc_html($menu_item->title) .'</span>';
    174             $item .= '<span class="item-controls">';
    175             $item .= '<span class="item-type">'. esc_html($menu_item->type) .'</span>';
     192            $output .= '<dl><dt>';
     193            $output .= '<span class="item-title">'. esc_html($menu_item->title) .'</span>';
     194            $output .= '<span class="item-controls">';
     195            $output .= '<span class="item-type">'. esc_html($menu_item->append) .'</span>';
    176196           
    177197            // Actions
    178             $item .= '<a class="item-edit thickbox" id="edit'. esc_attr( $menu_item->menu_order ) .'" value="'. esc_attr( $menu_item->menu_order ) .'" title="'. __('Edit Menu Item') .'" href="#TB_inline?height=380&width=300&inlineId=menu-item-settings">'. __('Edit') .'</a> | ';
    179             $item .= '<a class="item-delete" id="delete'. esc_attr( $menu_item->menu_order ) .'" value="'. esc_attr( $menu_item->menu_order ) .'">'. __('Delete') .'</a>';
    180            
    181             $item .= '</dt></dl>';
     198            $output .= '<a class="item-edit thickbox" id="edit'. esc_attr( $menu_item->menu_order ) .'" value="'. esc_attr( $menu_item->menu_order ) .'" title="'. __('Edit Menu Item') .'" href="#TB_inline?height=540&width=300&inlineId=menu-item-settings">'. __('Edit') .'</a> | ';
     199            $output .= '<a class="item-delete" id="delete'. esc_attr( $menu_item->menu_order ) .'" value="'. esc_attr( $menu_item->menu_order ) .'">'. __('Delete') .'</a>';
     200           
     201            $output .= '</dt></dl>';
    182202           
    183203            // Menu Item Settings
    184             $item .= '<input type="hidden" id="item-dbid'. esc_attr( $menu_item->menu_order ) .'" name="item-dbid'. esc_attr( $menu_item->menu_order ) .'" value="'. esc_attr( $menu_item->ID ) .'" />';
    185             $item .= '<input type="hidden" id="item-postmenu'. esc_attr( $menu_item->menu_order ) .'" name="item-postmenu'. esc_attr( $menu_item->menu_order ) .'" value="'. esc_attr( get_post_meta( $menu_item->ID, 'object_id', true ) ) .'" />';
    186             $item .= '<input type="hidden" id="item-parent'. esc_attr( $menu_item->menu_order ) .'" name="item-parent'. esc_attr( $menu_item->menu_order ) .'" value="'. esc_attr( $menu_item->parent_item ) .'" />';
    187             $item .= '<input type="hidden" id="item-position'. esc_attr( $menu_item->menu_order ) .'" name="item-position'. esc_attr( $menu_item->menu_order ) .'" value="'. esc_attr( $menu_item->menu_order ) .'" />';
    188             $item .= '<input type="hidden" id="item-type'. esc_attr( $menu_item->menu_order ) .'" name="item-type'. esc_attr( $menu_item->menu_order ) .'" value="'. esc_attr( get_post_meta( $menu_item->ID, 'menu_type', true ) ) .'" />';
    189             $item .= '<input type="hidden" id="item-title'. esc_attr( $menu_item->menu_order ) .'" name="item-title'. esc_attr( $menu_item->menu_order ) .'" value="'. esc_attr( $menu_item->title ) .'" />';
    190             $item .= '<input type="hidden" id="item-url'. esc_attr( $menu_item->menu_order ) .'" name="item-url'. esc_attr( $menu_item->menu_order ) .'" value="'. esc_attr( $menu_item->link ) .'" />';
    191             $item .= '<input type="hidden" id="item-description'. esc_attr( $menu_item->menu_order ) .'" name="item-description'. esc_attr( $menu_item->menu_order ) .'" value="'. esc_attr( $menu_item->description ) .'" />';
    192             $item .= '<input type="hidden" id="item-attr-title'. esc_attr( $menu_item->menu_order ) .'" name="item-attr-title'. esc_attr( $menu_item->menu_order ) .'" value="'.esc_attr( $menu_item->post_excerpt )  .'" />';
    193             $item .= '<input type="hidden" id="item-target'. esc_attr( $menu_item->menu_order ) .'" name="item-target'. esc_attr( $menu_item->menu_order ) .'" value="'. esc_attr( get_post_meta( $menu_item->ID, 'menu_new_window', true ) ? '1' : '0' ) .'" />';
    194             break;
    195            
    196         case 'default':
    197             $menu_id = 'menu-item-' . $menu_item->ID;
    198             $item .= '<label class="item-title"><input type="checkbox" id="'. esc_attr($menu_id) .'" name="'. esc_attr( $menu_item->title ) .'" value="'. esc_attr( $menu_item->link ) .'" />'. $menu_item->title .'</label>';
    199            
    200             // Menu Item Settings
    201             $item .= '<input type="hidden" class="item-type" value="'. esc_attr( $menu_item->type ) .'" />';
    202             $item .= '<input type="hidden" class="item-title" value="'. esc_attr( $menu_item->title ) .'" />';
    203             $item .= '<input type="hidden" class="item-url" value="'. esc_attr( $menu_item->link ) .'" />';
    204             $item .= '<input type="hidden" class="item-dbid" value="'. esc_attr( $menu_item->ID ) .'" />';
    205             $item .= '<input type="hidden" class="item-parent" value="'. esc_attr( $menu_item->parent_item ) .'" />';
    206             $item .= '<input type="hidden" class="item-description" value="'. esc_attr( $menu_item->description ) .'" />';
    207             break;
    208     }
    209     return apply_filters( 'wp_get_nav_menu_item', $item );
     204            $output .= '<input type="hidden" name="menu-item-db-id[]" id="menu-item-db-id'. esc_attr( $menu_item->menu_order ) .'" value="'. esc_attr( $menu_item->ID ) .'" />';
     205            $output .= '<input type="hidden" name="menu-item-object-id[]" id="menu-item-object-id'. esc_attr( $menu_item->menu_order ) .'" value="'. esc_attr( $menu_item->object_id ) .'" />';
     206            $output .= '<input type="hidden" name="menu-item-parent-id[]" id="menu-item-parent-id'. esc_attr( $menu_item->menu_order ) .'" value="'. esc_attr( $menu_item->post_parent ) .'" />';
     207            $output .= '<input type="hidden" name="menu-item-position[]" id="menu-item-position'. esc_attr( $menu_item->menu_order ) .'" value="'. esc_attr( $menu_item->menu_order ) .'" />';
     208            $output .= '<input type="hidden" name="menu-item-type[]" id="menu-item-type'. esc_attr( $menu_item->menu_order ) .'" value="'. esc_attr( $menu_item->type ) .'" />';
     209            $output .= '<input type="hidden" name="menu-item-append[]" id="menu-item-append'. esc_attr( $menu_item->menu_order ) .'" value="'. esc_attr( $menu_item->append ) .'" />';
     210            $output .= '<input type="hidden" name="menu-item-title[]" id="menu-item-title'. esc_attr( $menu_item->menu_order ) .'" value="'. esc_attr( $menu_item->title ) .'" />';
     211            $output .= '<input type="hidden" name="menu-item-url[]" id="menu-item-url'. esc_attr( $menu_item->menu_order ) .'" value="'. esc_attr( $menu_item->url ) .'" />';
     212            $output .= '<input type="hidden" name="menu-item-description[]" id="menu-item-description'. esc_attr( $menu_item->menu_order ) .'" value="'. esc_attr( $menu_item->description ) .'" />';
     213            $output .= '<input type="hidden" name="menu-item-classes[]" id="menu-item-classes'. esc_attr( $menu_item->menu_order ) .'" value="'. esc_attr( $menu_item->classes ) .'" />';
     214            $output .= '<input type="hidden" name="menu-item-xfn[]" id="menu-item-xfn'. esc_attr( $menu_item->menu_order ) .'" value="'. esc_attr( $menu_item->xfn ) .'" />';
     215            $output .= '<input type="hidden" name="menu-item-attr-title[]" id="menu-item-attr-title'. esc_attr( $menu_item->menu_order ) .'" value="'.esc_attr( $menu_item->post_excerpt )  .'" />';
     216            $output .= '<input type="hidden" name="menu-item-target[]" id="menu-item-target'. esc_attr( $menu_item->menu_order ) .'" value="'. esc_attr( $menu_item->target ) .'" />';
     217            break;
     218       
     219        case 'custom':
     220            $menu_id = 'menu-item-' . $menu_item->db_id;
     221            $output .= '<label class="menu-item-title"><input type="checkbox" id="'. esc_attr( $menu_id ) .'" name="'. esc_attr( $menu_item->title ) .'" value="'. esc_attr( $menu_item->url ) .'" />'. $menu_item->title .'</label>';
     222           
     223            // Menu item hidden fields
     224            $output .= '<input type="hidden" class="menu-item-db-id" value="'. esc_attr( $menu_item->db_id ) .'" />';
     225            $output .= '<input type="hidden" class="menu-item-object-id" value="'. esc_attr( $menu_item->object_id ) .'" />';
     226            $output .= '<input type="hidden" class="menu-item-parent-id" value="'. esc_attr( $menu_item->parent_id ) .'" />';
     227            $output .= '<input type="hidden" class="menu-item-type" value="'. esc_attr( $menu_item->type ) .'" />';
     228            $output .= '<input type="hidden" class="menu-item-append" value="'. esc_attr( $menu_item->append ) .'" />';
     229            $output .= '<input type="hidden" class="menu-item-title" value="'. esc_attr( $menu_item->title ) .'" />';
     230            $output .= '<input type="hidden" class="menu-item-url" value="'. esc_attr( $menu_item->url ) .'" />';
     231            $output .= '<input type="hidden" class="menu-item-target" value="'. esc_attr( $menu_item->target ) .'" />';
     232            $output .= '<input type="hidden" class="menu-item-attr_title" value="'. esc_attr( $menu_item->attr_title ) .'" />';
     233            $output .= '<input type="hidden" class="menu-item-description" value="'. esc_attr( $menu_item->description ) .'" />';
     234            $output .= '<input type="hidden" class="menu-item-classes" value="'. esc_attr( $menu_item->classes ) .'" />';
     235            $output .= '<input type="hidden" class="menu-item-xfn" value="'. esc_attr( $menu_item->xfn ) .'" />';
     236            break;
     237       
     238        case 'taxonomy':
     239        case 'post_type':
     240            $menu_id = 'menu-item-' . $menu_item->db_id;
     241            $output .= '<label class="menu-item-title"><input type="checkbox" id="'. esc_attr( $menu_id ) .'" name="'. esc_attr( $menu_item->title ) .'" value="'. esc_attr( $menu_item->url ) .'" />'. $menu_item->title .'</label>';
     242           
     243            // Menu item hidden fields
     244            $output .= '<input type="hidden" class="menu-item-db-id" value="0" />';
     245            $output .= '<input type="hidden" class="menu-item-object-id" value="'. esc_attr( $menu_item->object_id ) .'" />';
     246            $output .= '<input type="hidden" class="menu-item-parent-id" value="'. esc_attr( $menu_item->parent_id ) .'" />';
     247            $output .= '<input type="hidden" class="menu-item-type" value="'. esc_attr( $menu_item->type ) .'" />';
     248            $output .= '<input type="hidden" class="menu-item-append" value="'. esc_attr( $menu_item->append ) .'" />';
     249            $output .= '<input type="hidden" class="menu-item-title" value="'. esc_attr( $menu_item->title ) .'" />';
     250            $output .= '<input type="hidden" class="menu-item-url" value="'. esc_attr( $menu_item->url ) .'" />';
     251            $output .= '<input type="hidden" class="menu-item-append" value="'. esc_attr( $menu_item->append ) .'" />';
     252            break;
     253    }
     254   
     255    return $output;
    210256}
    211257?>
Note: See TracChangeset for help on using the changeset viewer.