- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/wp-includes/nav-menu-template.php
r14971 r15235 69 69 $indent = ( $depth ) ? str_repeat( "\t", $depth ) : ''; 70 70 71 $classes = $value = ''; 72 73 $classes = array( 'menu-item', 'menu-item-type-' . $item->type ); 74 if ( !empty($item->classes) ) 75 $classes = array_merge( $classes, $item->classes ); 76 77 if ( 'custom' != $item->type ) { 78 $classes[] = 'menu-item-object-' . $item->object; 79 $classes[] = 'menu-item-object-' . $item->type . '-' . $item->object_id; 80 if ( 'post_type' == $item->type && 'page' == $item->object ) { 81 // Back compat classes for pages to match wp_page_menu() 82 $classes[] = 'page_item'; 83 $classes[] = 'page-item-' . $item->object_id; 84 if ( ! empty( $item->classes ) ) { 85 if ( in_array('current-menu-item', $classes) ) 86 $classes[] = 'current_page_item'; 87 if ( in_array('current-menu-parent', $classes) ) 88 $classes[] = 'current_page_parent'; 89 if ( in_array('current-menu-ancestor', $classes) ) 90 $classes[] = 'current_page_ancestor'; 91 } 92 } 93 } elseif ( 'custom' == $item->type && in_array('current-menu-item', $classes) && in_array('menu-item-home', $classes) ) { 94 // Back compat for home limk to match wp_page_menu() 95 $classes[] = 'current_page_item'; 96 } 97 98 $classes = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) ); 99 $classes = ' class="' . esc_attr( $classes ) . '"'; 100 101 $output .= $indent . '<li id="menu-item-'. $item->ID . '"' . $value . $classes .'>'; 71 $class_names = $value = ''; 72 73 $classes = empty( $item->classes ) ? array() : (array) $item->classes; 74 75 $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) ); 76 $class_names = ' class="' . esc_attr( $class_names ) . '"'; 77 78 $output .= $indent . '<li id="menu-item-'. $item->ID . '"' . $value . $class_names .'>'; 102 79 103 80 $attributes = ! empty( $item->attr_title ) ? ' title="' . esc_attr( $item->attr_title ) .'"' : ''; … … 129 106 130 107 /** 131 * Create HTML list of nav menu input items.132 *133 * @package WordPress134 * @since 3.0.0135 * @uses Walker_Nav_Menu136 */137 class Walker_Nav_Menu_Checklist extends Walker_Nav_Menu {138 139 /**140 * @see Walker::start_el()141 * @since 3.0.0142 *143 * @param string $output Passed by reference. Used to append additional content.144 * @param object $item Menu item data object.145 * @param int $depth Depth of menu item. Used for padding.146 * @param int $current_page Menu item ID.147 * @param object $args148 */149 function start_el(&$output, $item, $depth, $args) {150 global $_nav_menu_placeholder;151 152 $_nav_menu_placeholder = ( 0 > $_nav_menu_placeholder ) ? intval($_nav_menu_placeholder) - 1 : -1;153 $possible_object_id = isset( $item->post_type ) && 'nav_menu_item' == $item->post_type ? $item->object_id : $_nav_menu_placeholder;154 $possible_db_id = ( ! empty( $item->ID ) ) && ( 0 < $possible_object_id ) ? (int) $item->ID : 0;155 156 $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';157 158 $output .= $indent . '<li>';159 $output .= '<label class="menu-item-title">';160 $output .= '<input type="checkbox" class="menu-item-checkbox';161 if ( ! empty( $item->_add_to_top ) ) {162 $output .= ' add-to-top';163 }164 $output .= '" name="menu-item[' . $possible_object_id . '][menu-item-object-id]" value="'. esc_attr( $item->object_id ) .'" /> ';165 $output .= empty( $item->label ) ? esc_html( $item->title ) : esc_html( $item->label );166 $output .= '</label>';167 168 // Menu item hidden fields169 $output .= '<input type="hidden" class="menu-item-db-id" name="menu-item[' . $possible_object_id . '][menu-item-db-id]" value="' . $possible_db_id . '" />';170 $output .= '<input type="hidden" class="menu-item-object" name="menu-item[' . $possible_object_id . '][menu-item-object]" value="'. esc_attr( $item->object ) .'" />';171 $output .= '<input type="hidden" class="menu-item-parent-id" name="menu-item[' . $possible_object_id . '][menu-item-parent-id]" value="'. esc_attr( $item->menu_item_parent ) .'" />';172 $output .= '<input type="hidden" class="menu-item-type" name="menu-item[' . $possible_object_id . '][menu-item-type]" value="'. esc_attr( $item->type ) .'" />';173 $output .= '<input type="hidden" class="menu-item-title" name="menu-item[' . $possible_object_id . '][menu-item-title]" value="'. esc_attr( $item->title ) .'" />';174 $output .= '<input type="hidden" class="menu-item-url" name="menu-item[' . $possible_object_id . '][menu-item-url]" value="'. esc_attr( $item->url ) .'" />';175 $output .= '<input type="hidden" class="menu-item-target" name="menu-item[' . $possible_object_id . '][menu-item-target]" value="'. esc_attr( $item->target ) .'" />';176 $output .= '<input type="hidden" class="menu-item-attr_title" name="menu-item[' . $possible_object_id . '][menu-item-attr_title]" value="'. esc_attr( $item->attr_title ) .'" />';177 $output .= '<input type="hidden" class="menu-item-description" name="menu-item[' . $possible_object_id . '][menu-item-description]" value="'. esc_attr( $item->description ) .'" />';178 $output .= '<input type="hidden" class="menu-item-classes" name="menu-item[' . $possible_object_id . '][menu-item-classes]" value="'. esc_attr( implode( ' ', $item->classes ) ) .'" />';179 $output .= '<input type="hidden" class="menu-item-xfn" name="menu-item[' . $possible_object_id . '][menu-item-xfn]" value="'. esc_attr( $item->xfn ) .'" />';180 }181 }182 183 /**184 108 * Displays a navigation menu. 185 109 * … … 187 111 * 188 112 * menu - The menu that is desired. Accepts (matching in order) id, slug, name. Defaults to blank. 189 * menu_class - CSS class to use for the ul container of the menu list. Defaults to 'menu'. 113 * menu_class - CSS class to use for the ul element which forms the menu. Defaults to 'menu'. 114 * menu_id - The ID that is applied to the ul element which forms the menu. Defaults to the menu slug, incremented. 190 115 * container - Whether to wrap the ul, and what to wrap it with. Defaults to 'div'. 191 * conatiner_class - the class that is applied to the container. Defaults to blank. 116 * container_class - the class that is applied to the container. Defaults to 'menu-{menu slug}-container'. 117 * container_id - The ID that is applied to the container. Defaults to blank. 192 118 * fallback_cb - If the menu doesn't exists, a callback function will fire. Defaults to 'wp_page_menu'. 193 119 * before - Text before the link text. … … 198 124 * depth - how many levels of the hierarchy are to be included. 0 means all. Defaults to 0. 199 125 * walker - allows a custom walker to be specified. 200 * context - the context the menu is used in.201 126 * 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. 202 127 * … … 206 131 */ 207 132 function wp_nav_menu( $args = array() ) { 208 $defaults = array( 'menu' => '', 'container' => 'div', 'container_class' => '', 'menu_class' => 'menu', 'echo' => true, 209 'fallback_cb' => 'wp_page_menu', 'before' => '', 'after' => '', 'link_before' => '', 'link_after' => '', 210 'depth' => 0, 'walker' => '', 'context' => 'frontend', 'theme_location' => '' ); 133 static $menu_id_slugs = array(); 134 135 $defaults = array( 'menu' => '', 'container' => 'div', 'container_class' => '', 'container_id' => '', 'menu_class' => 'menu', 'menu_id' => '', 136 'echo' => true, 'fallback_cb' => 'wp_page_menu', 'before' => '', 'after' => '', 'link_before' => '', 'link_after' => '', 137 'depth' => 0, 'walker' => '', 'theme_location' => '' ); 211 138 212 139 $args = wp_parse_args( $args, $defaults ); … … 236 163 $menu_items = wp_get_nav_menu_items( $menu->term_id ); 237 164 238 // If no menu was found or if the menu has no items , call the fallback_cb239 if ( !$menu || is_wp_error($menu) || ( isset($menu_items) && empty($menu_items) ) ) {240 if ( 'frontend' == $args->context && ( function_exists($args->fallback_cb) || is_callable( $args->fallback_cb ) ) ) {165 // If no menu was found or if the menu has no items and no location was requested, call the fallback_cb if it exists 166 if ( ( !$menu || is_wp_error($menu) || ( isset($menu_items) && empty($menu_items) && !$args->theme_location ) ) 167 && ( function_exists($args->fallback_cb) || is_callable( $args->fallback_cb ) ) ) 241 168 return call_user_func( $args->fallback_cb, (array) $args ); 242 }243 }244 169 245 170 // If no fallback function was specified and the menu doesn't exists, bail. … … 247 172 return false; 248 173 249 $nav_menu = ''; 250 $items = ''; 251 $container_allowedtags = apply_filters( 'wp_nav_menu_container_allowedtags', array( 'div', 'nav' ) ); 252 253 if ( in_array( $args->container, $container_allowedtags ) ) { 254 $class = $args->container_class ? ' class="' . esc_attr($args->container_class) . '"' : ' class="menu-'. $menu->slug .'-container"'; 255 $nav_menu .= '<'. $args->container . $class .'>'; 174 $nav_menu = $items = ''; 175 176 $show_container = false; 177 if ( $args->container ) { 178 $allowed_tags = apply_filters( 'wp_nav_menu_container_allowedtags', array( 'div', 'nav' ) ); 179 if ( in_array( $args->container, $allowed_tags ) ) { 180 $show_container = true; 181 $class = $args->container_class ? ' class="' . esc_attr( $args->container_class ) . '"' : ' class="menu-'. $menu->slug .'-container"'; 182 $id = $args->container_id ? ' id="' . esc_attr( $args->container_id ) . '"' : ''; 183 $nav_menu .= '<'. $args->container . $id . $class . '>'; 184 } 256 185 } 257 186 258 187 // Set up the $menu_item variables 259 if ( 'frontend' == $args->context ) 260 _wp_menu_item_classes_by_context( $menu_items ); 188 _wp_menu_item_classes_by_context( $menu_items ); 261 189 262 190 $sorted_menu_items = array(); … … 270 198 271 199 // Attributes 272 $attributes = ' id="menu-' . $menu->slug . '"'; 200 if ( ! empty( $args->menu_id ) ) { 201 $slug = $args->menu_id; 202 } else { 203 $slug = 'menu-' . $menu->slug; 204 while ( in_array( $slug, $menu_id_slugs ) ) { 205 if ( preg_match( '#-(\d+)$#', $slug, $matches ) ) 206 $slug = preg_replace('#-(\d+)$#', '-' . ++$matches[1], $slug); 207 else 208 $slug = $slug . '-1'; 209 } 210 } 211 $menu_id_slugs[] = $slug; 212 $attributes = ' id="' . $slug . '"'; 273 213 $attributes .= $args->menu_class ? ' class="'. $args->menu_class .'"' : ''; 274 214 … … 283 223 $nav_menu .= '</ul>'; 284 224 285 if ( in_array( $args->container, $container_allowedtags ))286 $nav_menu .= '</' . $args->container .'>';225 if ( $show_container ) 226 $nav_menu .= '</' . $args->container . '>'; 287 227 288 228 $nav_menu = apply_filters( 'wp_nav_menu', $nav_menu, $args ); … … 295 235 296 236 /** 297 * Add the class property classes for the current frontendcontext, if applicable.237 * Add the class property classes for the current context, if applicable. 298 238 * 299 239 * @access private … … 311 251 $active_parent_item_ids = array(); 312 252 $active_parent_object_ids = array(); 253 $possible_taxonomy_ancestors = array(); 313 254 $possible_object_parents = array(); 314 255 $home_page_id = (int) get_option( 'page_for_posts' ); … … 317 258 foreach ( (array) get_object_taxonomies( $queried_object->post_type ) as $taxonomy ) { 318 259 if ( is_taxonomy_hierarchical( $taxonomy ) ) { 260 $term_hierarchy = _get_term_hierarchy( $taxonomy ); 319 261 $terms = wp_get_object_terms( $queried_object_id, $taxonomy, array( 'fields' => 'ids' ) ); 320 if ( is_array( $terms ) ) 262 if ( is_array( $terms ) ) { 321 263 $possible_object_parents = array_merge( $possible_object_parents, $terms ); 264 $term_to_ancestor = array(); 265 foreach ( (array) $term_hierarchy as $anc => $descs ) { 266 foreach ( (array) $descs as $desc ) 267 $term_to_ancestor[ $desc ] = $anc; 268 } 269 270 foreach ( $terms as $desc ) { 271 do { 272 $possible_taxonomy_ancestors[ $taxonomy ][] = $desc; 273 if ( isset( $term_to_ancestor[ $desc ] ) ) { 274 $_desc = $term_to_ancestor[ $desc ]; 275 unset( $term_to_ancestor[ $desc ] ); 276 $desc = $_desc; 277 } else { 278 $desc = 0; 279 } 280 } while ( ! empty( $desc ) ); 281 } 282 } 322 283 } 323 284 } 324 285 } elseif ( ! empty( $queried_object->post_type ) && is_post_type_hierarchical( $queried_object->post_type ) ) { 325 286 _get_post_ancestors( $queried_object ); 287 } elseif ( ! empty( $queried_object->taxonomy ) && is_taxonomy_hierarchical( $queried_object->taxonomy ) ) { 288 $term_hierarchy = _get_term_hierarchy( $queried_object->taxonomy ); 289 $term_to_ancestor = array(); 290 foreach ( (array) $term_hierarchy as $anc => $descs ) { 291 foreach ( (array) $descs as $desc ) 292 $term_to_ancestor[ $desc ] = $anc; 293 } 294 $desc = $queried_object->term_id; 295 do { 296 $possible_taxonomy_ancestors[ $queried_object->taxonomy ][] = $desc; 297 if ( isset( $term_to_ancestor[ $desc ] ) ) { 298 $_desc = $term_to_ancestor[ $desc ]; 299 unset( $term_to_ancestor[ $desc ] ); 300 $desc = $_desc; 301 } else { 302 $desc = 0; 303 } 304 } while ( ! empty( $desc ) ); 326 305 } 327 306 … … 329 308 330 309 foreach ( (array) $menu_items as $key => $menu_item ) { 310 $classes = (array) $menu_item->classes; 311 $classes[] = 'menu-item'; 312 $classes[] = 'menu-item-type-' . $menu_item->type; 313 331 314 // if the menu item corresponds to a taxonomy term for the currently-queried non-hierarchical post object 332 315 if ( $wp_query->is_singular && 'taxonomy' == $menu_item->type && in_array( $menu_item->object_id, $possible_object_parents ) ) { … … 344 327 ) 345 328 ) { 346 $menu_items[$key]->classes[] = 'current-menu-item'; 329 $classes[] = 'current-menu-item'; 330 if ( 'post_type' == $menu_item->type && 'page' == $menu_item->object ) { 331 // Back compat classes for pages to match wp_page_menu() 332 $classes[] = 'page_item'; 333 $classes[] = 'page-item-' . $menu_item->object_id; 334 $classes[] = 'current_page_item'; 335 } 347 336 $active_parent_item_ids[] = (int) $menu_item->menu_item_parent; 348 337 $active_parent_object_ids[] = (int) $menu_item->post_parent; … … 354 343 $item_url = strpos( $menu_item->url, '#' ) ? substr( $menu_item->url, 0, strpos( $menu_item->url, '#' ) ) : $menu_item->url; 355 344 if ( $item_url == $current_url ) { 356 $menu_items[$key]->classes[] = 'current-menu-item'; 357 if ( untrailingslashit($current_url) == home_url() ) 358 $menu_items[$key]->classes[] = 'menu-item-home'; 345 $classes[] = 'current-menu-item'; 346 if ( untrailingslashit($current_url) == home_url() ) { 347 $classes[] = 'menu-item-home'; 348 // Back compat for home limk to match wp_page_menu() 349 $classes[] = 'current_page_item'; 350 } 359 351 $active_parent_item_ids[] = (int) $menu_item->menu_item_parent; 360 352 $active_parent_object_ids[] = (int) $menu_item->post_parent; … … 362 354 } 363 355 } 364 356 365 357 // back-compat with wp_page_menu: add "current_page_parent" to static home page link for any non-page query 366 if ( ! empty( $home_page_id ) && 'post_type' == $menu_item->type && empty( $wp_query->is_page ) && $home_page_id == $menu_item->object_id ) 367 $menu_items[$key]->classes[] = 'current_page_parent'; 358 if ( ! empty( $home_page_id ) && 'post_type' == $menu_item->type && empty( $wp_query->is_page ) && $home_page_id == $menu_item->object_id ) 359 $classes[] = 'current_page_parent'; 360 361 $menu_items[$key]->classes = array_unique( $classes ); 368 362 } 369 363 … … 373 367 // set parent's class 374 368 foreach ( (array) $menu_items as $key => $parent_item ) { 369 $classes = (array) $parent_item->classes; 370 375 371 if ( 376 372 isset( $parent_item->type ) && 377 'post_type' == $parent_item->type && 378 ! empty( $queried_object->post_type ) && 379 is_post_type_hierarchical( $queried_object->post_type ) && 380 in_array( $parent_item->object_id, $queried_object->ancestors ) 381 ) 382 $menu_items[$key]->classes[] = 'current-' . $queried_object->post_type . '-ancestor current-menu-ancestor'; 373 ( 374 // ancestral post object 375 ( 376 'post_type' == $parent_item->type && 377 ! empty( $queried_object->post_type ) && 378 is_post_type_hierarchical( $queried_object->post_type ) && 379 in_array( $parent_item->object_id, $queried_object->ancestors ) 380 ) || 381 382 // ancestral term 383 ( 384 'taxonomy' == $parent_item->type && 385 isset( $possible_taxonomy_ancestors[ $parent_item->object ] ) && 386 in_array( $parent_item->object_id, $possible_taxonomy_ancestors[ $parent_item->object ] ) 387 ) 388 ) 389 ) { 390 $classes[] = empty( $queried_object->taxonomy ) ? 'current-' . $queried_object->post_type . '-ancestor' : 'current-' . $queried_object->taxonomy . '-ancestor'; 391 $classes[] = 'current-menu-ancestor'; 392 } 393 383 394 if ( in_array( $parent_item->db_id, $active_parent_item_ids ) ) 384 $ menu_items[$key]->classes[] = 'current-menu-parent';395 $classes[] = 'current-menu-parent'; 385 396 if ( in_array( $parent_item->object_id, $active_parent_object_ids ) ) 386 $menu_items[$key]->classes[] = 'current-' . $active_object . '-parent'; 397 $classes[] = 'current-' . $active_object . '-parent'; 398 399 if ( 'post_type' == $parent_item->type && 'page' == $parent_item->object ) { 400 // Back compat classes for pages to match wp_page_menu() 401 if ( in_array('current-menu-parent', $classes) ) 402 $classes[] = 'current_page_parent'; 403 if ( in_array('current-menu-ancestor', $classes) ) 404 $classes[] = 'current_page_ancestor'; 405 } 406 407 $menu_items[$key]->classes = array_unique( $classes ); 387 408 } 388 409 }
Note: See TracChangeset
for help on using the changeset viewer.