[ Index ]

WordPress Cross Reference

title

Body

[close]

/wp-includes/ -> nav-menu-template.php (source)

   1  <?php
   2  /**
   3   * Navigation Menu template functions
   4   *
   5   * @package WordPress
   6   * @subpackage Nav_Menus
   7   * @since 3.0.0
   8   */
   9  
  10  /**
  11   * Create HTML list of nav menu items.
  12   *
  13   * @package WordPress
  14   * @since 3.0.0
  15   * @uses Walker
  16   */
  17  class Walker_Nav_Menu extends Walker {
  18      /**
  19       * What the class handles.
  20       *
  21       * @see Walker::$tree_type
  22       * @since 3.0.0
  23       * @var string
  24       */
  25      var $tree_type = array( 'post_type', 'taxonomy', 'custom' );
  26  
  27      /**
  28       * Database fields to use.
  29       *
  30       * @see Walker::$db_fields
  31       * @since 3.0.0
  32       * @todo Decouple this.
  33       * @var array
  34       */
  35      var $db_fields = array( 'parent' => 'menu_item_parent', 'id' => 'db_id' );
  36  
  37      /**
  38       * Starts the list before the elements are added.
  39       *
  40       * @see Walker::start_lvl()
  41       *
  42       * @since 3.0.0
  43       *
  44       * @param string $output Passed by reference. Used to append additional content.
  45       * @param int    $depth  Depth of menu item. Used for padding.
  46       * @param array  $args   An array of arguments. @see wp_nav_menu()
  47       */
  48  	function start_lvl( &$output, $depth = 0, $args = array() ) {
  49          $indent = str_repeat("\t", $depth);
  50          $output .= "\n$indent<ul class=\"sub-menu\">\n";
  51      }
  52  
  53      /**
  54       * Ends the list of after the elements are added.
  55       *
  56       * @see Walker::end_lvl()
  57       *
  58       * @since 3.0.0
  59       *
  60       * @param string $output Passed by reference. Used to append additional content.
  61       * @param int    $depth  Depth of menu item. Used for padding.
  62       * @param array  $args   An array of arguments. @see wp_nav_menu()
  63       */
  64  	function end_lvl( &$output, $depth = 0, $args = array() ) {
  65          $indent = str_repeat("\t", $depth);
  66          $output .= "$indent</ul>\n";
  67      }
  68  
  69      /**
  70       * Start the element output.
  71       *
  72       * @see Walker::start_el()
  73       *
  74       * @since 3.0.0
  75       *
  76       * @param string $output Passed by reference. Used to append additional content.
  77       * @param object $item   Menu item data object.
  78       * @param int    $depth  Depth of menu item. Used for padding.
  79       * @param array  $args   An array of arguments. @see wp_nav_menu()
  80       * @param int    $id     Current item ID.
  81       */
  82  	function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
  83          $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
  84  
  85          $class_names = $value = '';
  86  
  87          $classes = empty( $item->classes ) ? array() : (array) $item->classes;
  88          $classes[] = 'menu-item-' . $item->ID;
  89  
  90          /**
  91           * Filter the CSS class(es) applied to a menu item's <li>.
  92           *
  93           * @since 3.0.0
  94           *
  95           * @param array  $classes The CSS classes that are applied to the menu item's <li>.
  96           * @param object $item    The current menu item.
  97           * @param array  $args    An array of arguments. @see wp_nav_menu()
  98           */
  99          $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args ) );
 100          $class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';
 101  
 102          /**
 103           * Filter the ID applied to a menu item's <li>.
 104           *
 105           * @since 3.0.1
 106           *
 107           * @param string The ID that is applied to the menu item's <li>.
 108           * @param object $item The current menu item.
 109           * @param array $args An array of arguments. @see wp_nav_menu()
 110           */
 111          $id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args );
 112          $id = $id ? ' id="' . esc_attr( $id ) . '"' : '';
 113  
 114          $output .= $indent . '<li' . $id . $value . $class_names .'>';
 115  
 116          $atts = array();
 117          $atts['title']  = ! empty( $item->attr_title ) ? $item->attr_title : '';
 118          $atts['target'] = ! empty( $item->target )     ? $item->target     : '';
 119          $atts['rel']    = ! empty( $item->xfn )        ? $item->xfn        : '';
 120          $atts['href']   = ! empty( $item->url )        ? $item->url        : '';
 121  
 122          /**
 123           * Filter the HTML attributes applied to a menu item's <a>.
 124           *
 125           * @since 3.6.0
 126           *
 127           * @param array $atts {
 128           *     The HTML attributes applied to the menu item's <a>, empty strings are ignored.
 129           *
 130           *     @type string $title  The title attribute.
 131           *     @type string $target The target attribute.
 132           *     @type string $rel    The rel attribute.
 133           *     @type string $href   The href attribute.
 134           * }
 135           * @param object $item The current menu item.
 136           * @param array  $args An array of arguments. @see wp_nav_menu()
 137           */
 138          $atts = apply_filters( 'nav_menu_link_attributes', $atts, $item, $args );
 139  
 140          $attributes = '';
 141          foreach ( $atts as $attr => $value ) {
 142              if ( ! empty( $value ) ) {
 143                  $value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value );
 144                  $attributes .= ' ' . $attr . '="' . $value . '"';
 145              }
 146          }
 147  
 148          $item_output = $args->before;
 149          $item_output .= '<a'. $attributes .'>';
 150          /** This filter is documented in wp-includes/post-template.php */
 151          $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
 152          $item_output .= '</a>';
 153          $item_output .= $args->after;
 154  
 155          /**
 156           * Filter a menu item's starting output.
 157           *
 158           * The menu item's starting output only includes $args->before, the opening <a>,
 159           * the menu item's title, the closing </a>, and $args->after. Currently, there is
 160           * no filter for modifying the opening and closing <li> for a menu item.
 161           *
 162           * @since 3.0.0
 163           *
 164           * @param string $item_output The menu item's starting HTML output.
 165           * @param object $item        Menu item data object.
 166           * @param int    $depth       Depth of menu item. Used for padding.
 167           * @param array  $args        An array of arguments. @see wp_nav_menu()
 168           */
 169          $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
 170      }
 171  
 172      /**
 173       * Ends the element output, if needed.
 174       *
 175       * @see Walker::end_el()
 176       *
 177       * @since 3.0.0
 178       *
 179       * @param string $output Passed by reference. Used to append additional content.
 180       * @param object $item   Page data object. Not used.
 181       * @param int    $depth  Depth of page. Not Used.
 182       * @param array  $args   An array of arguments. @see wp_nav_menu()
 183       */
 184  	function end_el( &$output, $item, $depth = 0, $args = array() ) {
 185          $output .= "</li>\n";
 186      }
 187  
 188  } // Walker_Nav_Menu
 189  
 190  /**
 191   * Displays a navigation menu.
 192   *
 193   * Optional $args contents:
 194   *
 195   * menu - The menu that is desired. Accepts (matching in order) id, slug, name. Defaults to blank.
 196   * menu_class - CSS class to use for the ul element which forms the menu. Defaults to 'menu'.
 197   * menu_id - The ID that is applied to the ul element which forms the menu. Defaults to the menu slug, incremented.
 198   * container - Whether to wrap the ul, and what to wrap it with. Defaults to 'div'.
 199   * container_class - the class that is applied to the container. Defaults to 'menu-{menu slug}-container'.
 200   * container_id - The ID that is applied to the container. Defaults to blank.
 201   * fallback_cb - If the menu doesn't exists, a callback function will fire. Defaults to 'wp_page_menu'. Set to false for no fallback.
 202   * before - Text before the link text.
 203   * after - Text after the link text.
 204   * link_before - Text before the link.
 205   * link_after - Text after the link.
 206   * echo - Whether to echo the menu or return it. Defaults to echo.
 207   * depth - how many levels of the hierarchy are to be included. 0 means all. Defaults to 0.
 208   * walker - allows a custom walker to be specified.
 209   * 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.
 210   * items_wrap - How the list items should be wrapped. Defaults to a ul with an id and class. Uses printf() format with numbered placeholders.
 211   *
 212   * @since 3.0.0
 213   *
 214   * @param array $args Arguments
 215   */
 216  function wp_nav_menu( $args = array() ) {
 217      static $menu_id_slugs = array();
 218  
 219      $defaults = array( 'menu' => '', 'container' => 'div', 'container_class' => '', 'container_id' => '', 'menu_class' => 'menu', 'menu_id' => '',
 220      '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>',
 221      'depth' => 0, 'walker' => '', 'theme_location' => '' );
 222  
 223      $args = wp_parse_args( $args, $defaults );
 224      /**
 225       * Filter the arguments used to display a navigation menu.
 226       *
 227       * @since 3.0.0
 228       *
 229       * @param array $args Arguments from {@see wp_nav_menu()}.
 230       */
 231      $args = apply_filters( 'wp_nav_menu_args', $args );
 232      $args = (object) $args;
 233  
 234      // Get the nav menu based on the requested menu
 235      $menu = wp_get_nav_menu_object( $args->menu );
 236  
 237      // Get the nav menu based on the theme_location
 238      if ( ! $menu && $args->theme_location && ( $locations = get_nav_menu_locations() ) && isset( $locations[ $args->theme_location ] ) )
 239          $menu = wp_get_nav_menu_object( $locations[ $args->theme_location ] );
 240  
 241      // get the first menu that has items if we still can't find a menu
 242      if ( ! $menu && !$args->theme_location ) {
 243          $menus = wp_get_nav_menus();
 244          foreach ( $menus as $menu_maybe ) {
 245              if ( $menu_items = wp_get_nav_menu_items( $menu_maybe->term_id, array( 'update_post_term_cache' => false ) ) ) {
 246                  $menu = $menu_maybe;
 247                  break;
 248              }
 249          }
 250      }
 251  
 252      // If the menu exists, get its items.
 253      if ( $menu && ! is_wp_error($menu) && !isset($menu_items) )
 254          $menu_items = wp_get_nav_menu_items( $menu->term_id, array( 'update_post_term_cache' => false ) );
 255  
 256      /*
 257       * If no menu was found:
 258       *  - Fall back (if one was specified), or bail.
 259       *
 260       * If no menu items were found:
 261       *  - Fall back, but only if no theme location was specified.
 262       *  - Otherwise, bail.
 263       */
 264      if ( ( !$menu || is_wp_error($menu) || ( isset($menu_items) && empty($menu_items) && !$args->theme_location ) )
 265          && $args->fallback_cb && is_callable( $args->fallback_cb ) )
 266              return call_user_func( $args->fallback_cb, (array) $args );
 267  
 268      if ( ! $menu || is_wp_error( $menu ) )
 269          return false;
 270  
 271      $nav_menu = $items = '';
 272  
 273      $show_container = false;
 274      if ( $args->container ) {
 275          /**
 276           * Filter the list of HTML tags that are valid for use as menu containers.
 277           *
 278           * @since 3.0.0
 279           *
 280           * @param array The acceptable HTML tags for use as menu containers, defaults as 'div' and 'nav'.
 281           */
 282          $allowed_tags = apply_filters( 'wp_nav_menu_container_allowedtags', array( 'div', 'nav' ) );
 283          if ( in_array( $args->container, $allowed_tags ) ) {
 284              $show_container = true;
 285              $class = $args->container_class ? ' class="' . esc_attr( $args->container_class ) . '"' : ' class="menu-'. $menu->slug .'-container"';
 286              $id = $args->container_id ? ' id="' . esc_attr( $args->container_id ) . '"' : '';
 287              $nav_menu .= '<'. $args->container . $id . $class . '>';
 288          }
 289      }
 290  
 291      // Set up the $menu_item variables
 292      _wp_menu_item_classes_by_context( $menu_items );
 293  
 294      $sorted_menu_items = $menu_items_with_children = array();
 295      foreach ( (array) $menu_items as $menu_item ) {
 296          $sorted_menu_items[ $menu_item->menu_order ] = $menu_item;
 297          if ( $menu_item->menu_item_parent )
 298              $menu_items_with_children[ $menu_item->menu_item_parent ] = true;
 299      }
 300  
 301      // Add the menu-item-has-children class where applicable
 302      if ( $menu_items_with_children ) {
 303          foreach ( $sorted_menu_items as &$menu_item ) {
 304              if ( isset( $menu_items_with_children[ $menu_item->ID ] ) )
 305                  $menu_item->classes[] = 'menu-item-has-children';
 306          }
 307      }
 308  
 309      unset( $menu_items, $menu_item );
 310  
 311      /**
 312       * Filter the sorted list of menu item objects before generating the menu's HTML.
 313       *
 314       * @since 3.1.0
 315       *
 316       * @param array $sorted_menu_items The menu items, sorted by each menu item's menu order.
 317       */
 318      $sorted_menu_items = apply_filters( 'wp_nav_menu_objects', $sorted_menu_items, $args );
 319  
 320      $items .= walk_nav_menu_tree( $sorted_menu_items, $args->depth, $args );
 321      unset($sorted_menu_items);
 322  
 323      // Attributes
 324      if ( ! empty( $args->menu_id ) ) {
 325          $wrap_id = $args->menu_id;
 326      } else {
 327          $wrap_id = 'menu-' . $menu->slug;
 328          while ( in_array( $wrap_id, $menu_id_slugs ) ) {
 329              if ( preg_match( '#-(\d+)$#', $wrap_id, $matches ) )
 330                  $wrap_id = preg_replace('#-(\d+)$#', '-' . ++$matches[1], $wrap_id );
 331              else
 332                  $wrap_id = $wrap_id . '-1';
 333          }
 334      }
 335      $menu_id_slugs[] = $wrap_id;
 336  
 337      $wrap_class = $args->menu_class ? $args->menu_class : '';
 338  
 339      /**
 340       * Filter the HTML list content for navigation menus.
 341       *
 342       * @since 3.0.0
 343       *
 344       * @param string $items The HTML list content for the menu items.
 345       * @param array $args Arguments from {@see wp_nav_menu()}.
 346       */
 347      $items = apply_filters( 'wp_nav_menu_items', $items, $args );
 348      /**
 349       * Filter the HTML list content for a specific navigation menu.
 350       *
 351       * @since 3.0.0
 352       *
 353       * @param string $items The HTML list content for the menu items.
 354       * @param array $args Arguments from {@see wp_nav_menu()}.
 355       */
 356      $items = apply_filters( "wp_nav_menu_{$menu->slug}_items", $items, $args );
 357  
 358      // Don't print any markup if there are no items at this point.
 359      if ( empty( $items ) )
 360          return false;
 361  
 362      $nav_menu .= sprintf( $args->items_wrap, esc_attr( $wrap_id ), esc_attr( $wrap_class ), $items );
 363      unset( $items );
 364  
 365      if ( $show_container )
 366          $nav_menu .= '</' . $args->container . '>';
 367  
 368      /**
 369       * Filter the HTML content for navigation menus.
 370       *
 371       * @since 3.0.0
 372       *
 373       * @param string $nav_menu The HTML content for the navigation menu.
 374       * @param array $args Arguments from {@see wp_nav_menu()}.
 375       */
 376      $nav_menu = apply_filters( 'wp_nav_menu', $nav_menu, $args );
 377  
 378      if ( $args->echo )
 379          echo $nav_menu;
 380      else
 381          return $nav_menu;
 382  }
 383  
 384  /**
 385   * Add the class property classes for the current context, if applicable.
 386   *
 387   * @access private
 388   * @since 3.0
 389   *
 390   * @param array $menu_items The current menu item objects to which to add the class property information.
 391   */
 392  function _wp_menu_item_classes_by_context( &$menu_items ) {
 393      global $wp_query, $wp_rewrite;
 394  
 395      $queried_object = $wp_query->get_queried_object();
 396      $queried_object_id = (int) $wp_query->queried_object_id;
 397  
 398      $active_object = '';
 399      $active_ancestor_item_ids = array();
 400      $active_parent_item_ids = array();
 401      $active_parent_object_ids = array();
 402      $possible_taxonomy_ancestors = array();
 403      $possible_object_parents = array();
 404      $home_page_id = (int) get_option( 'page_for_posts' );
 405  
 406      if ( $wp_query->is_singular && ! empty( $queried_object->post_type ) && ! is_post_type_hierarchical( $queried_object->post_type ) ) {
 407          foreach ( (array) get_object_taxonomies( $queried_object->post_type ) as $taxonomy ) {
 408              if ( is_taxonomy_hierarchical( $taxonomy ) ) {
 409                  $term_hierarchy = _get_term_hierarchy( $taxonomy );
 410                  $terms = wp_get_object_terms( $queried_object_id, $taxonomy, array( 'fields' => 'ids' ) );
 411                  if ( is_array( $terms ) ) {
 412                      $possible_object_parents = array_merge( $possible_object_parents, $terms );
 413                      $term_to_ancestor = array();
 414                      foreach ( (array) $term_hierarchy as $anc => $descs ) {
 415                          foreach ( (array) $descs as $desc )
 416                              $term_to_ancestor[ $desc ] = $anc;
 417                      }
 418  
 419                      foreach ( $terms as $desc ) {
 420                          do {
 421                              $possible_taxonomy_ancestors[ $taxonomy ][] = $desc;
 422                              if ( isset( $term_to_ancestor[ $desc ] ) ) {
 423                                  $_desc = $term_to_ancestor[ $desc ];
 424                                  unset( $term_to_ancestor[ $desc ] );
 425                                  $desc = $_desc;
 426                              } else {
 427                                  $desc = 0;
 428                              }
 429                          } while ( ! empty( $desc ) );
 430                      }
 431                  }
 432              }
 433          }
 434      } elseif ( ! empty( $queried_object->taxonomy ) && is_taxonomy_hierarchical( $queried_object->taxonomy ) ) {
 435          $term_hierarchy = _get_term_hierarchy( $queried_object->taxonomy );
 436          $term_to_ancestor = array();
 437          foreach ( (array) $term_hierarchy as $anc => $descs ) {
 438              foreach ( (array) $descs as $desc )
 439                  $term_to_ancestor[ $desc ] = $anc;
 440          }
 441          $desc = $queried_object->term_id;
 442          do {
 443              $possible_taxonomy_ancestors[ $queried_object->taxonomy ][] = $desc;
 444              if ( isset( $term_to_ancestor[ $desc ] ) ) {
 445                  $_desc = $term_to_ancestor[ $desc ];
 446                  unset( $term_to_ancestor[ $desc ] );
 447                  $desc = $_desc;
 448              } else {
 449                  $desc = 0;
 450              }
 451          } while ( ! empty( $desc ) );
 452      }
 453  
 454      $possible_object_parents = array_filter( $possible_object_parents );
 455  
 456      $front_page_url = home_url();
 457  
 458      foreach ( (array) $menu_items as $key => $menu_item ) {
 459  
 460          $menu_items[$key]->current = false;
 461  
 462          $classes = (array) $menu_item->classes;
 463          $classes[] = 'menu-item';
 464          $classes[] = 'menu-item-type-' . $menu_item->type;
 465          $classes[] = 'menu-item-object-' . $menu_item->object;
 466  
 467          // if the menu item corresponds to a taxonomy term for the currently-queried non-hierarchical post object
 468          if ( $wp_query->is_singular && 'taxonomy' == $menu_item->type && in_array( $menu_item->object_id, $possible_object_parents ) ) {
 469              $active_parent_object_ids[] = (int) $menu_item->object_id;
 470              $active_parent_item_ids[] = (int) $menu_item->db_id;
 471              $active_object = $queried_object->post_type;
 472  
 473          // if the menu item corresponds to the currently-queried post or taxonomy object
 474          } elseif (
 475              $menu_item->object_id == $queried_object_id &&
 476              (
 477                  ( ! empty( $home_page_id ) && 'post_type' == $menu_item->type && $wp_query->is_home && $home_page_id == $menu_item->object_id ) ||
 478                  ( 'post_type' == $menu_item->type && $wp_query->is_singular ) ||
 479                  ( 'taxonomy' == $menu_item->type && ( $wp_query->is_category || $wp_query->is_tag || $wp_query->is_tax ) && $queried_object->taxonomy == $menu_item->object )
 480              )
 481          ) {
 482              $classes[] = 'current-menu-item';
 483              $menu_items[$key]->current = true;
 484              $_anc_id = (int) $menu_item->db_id;
 485  
 486              while(
 487                  ( $_anc_id = get_post_meta( $_anc_id, '_menu_item_menu_item_parent', true ) ) &&
 488                  ! in_array( $_anc_id, $active_ancestor_item_ids )
 489              ) {
 490                  $active_ancestor_item_ids[] = $_anc_id;
 491              }
 492  
 493              if ( 'post_type' == $menu_item->type && 'page' == $menu_item->object ) {
 494                  // Back compat classes for pages to match wp_page_menu()
 495                  $classes[] = 'page_item';
 496                  $classes[] = 'page-item-' . $menu_item->object_id;
 497                  $classes[] = 'current_page_item';
 498              }
 499              $active_parent_item_ids[] = (int) $menu_item->menu_item_parent;
 500              $active_parent_object_ids[] = (int) $menu_item->post_parent;
 501              $active_object = $menu_item->object;
 502  
 503          // if the menu item corresponds to the currently-requested URL
 504          } elseif ( 'custom' == $menu_item->object ) {
 505              $_root_relative_current = untrailingslashit( $_SERVER['REQUEST_URI'] );
 506              $current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_root_relative_current );
 507              $raw_item_url = strpos( $menu_item->url, '#' ) ? substr( $menu_item->url, 0, strpos( $menu_item->url, '#' ) ) : $menu_item->url;
 508              $item_url = untrailingslashit( $raw_item_url );
 509              $_indexless_current = untrailingslashit( preg_replace( '/' . preg_quote( $wp_rewrite->index, '/' ) . '$/', '', $current_url ) );
 510  
 511              if ( $raw_item_url && in_array( $item_url, array( $current_url, $_indexless_current, $_root_relative_current ) ) ) {
 512                  $classes[] = 'current-menu-item';
 513                  $menu_items[$key]->current = true;
 514                  $_anc_id = (int) $menu_item->db_id;
 515  
 516                  while(
 517                      ( $_anc_id = get_post_meta( $_anc_id, '_menu_item_menu_item_parent', true ) ) &&
 518                      ! in_array( $_anc_id, $active_ancestor_item_ids )
 519                  ) {
 520                      $active_ancestor_item_ids[] = $_anc_id;
 521                  }
 522  
 523                  if ( in_array( home_url(), array( untrailingslashit( $current_url ), untrailingslashit( $_indexless_current ) ) ) ) {
 524                      // Back compat for home link to match wp_page_menu()
 525                      $classes[] = 'current_page_item';
 526                  }
 527                  $active_parent_item_ids[] = (int) $menu_item->menu_item_parent;
 528                  $active_parent_object_ids[] = (int) $menu_item->post_parent;
 529                  $active_object = $menu_item->object;
 530  
 531              // give front page item current-menu-item class when extra query arguments involved
 532              } elseif ( $item_url == $front_page_url && is_front_page() ) {
 533                  $classes[] = 'current-menu-item';
 534              }
 535  
 536              if ( untrailingslashit($item_url) == home_url() )
 537                  $classes[] = 'menu-item-home';
 538          }
 539  
 540          // back-compat with wp_page_menu: add "current_page_parent" to static home page link for any non-page query
 541          if ( ! empty( $home_page_id ) && 'post_type' == $menu_item->type && empty( $wp_query->is_page ) && $home_page_id == $menu_item->object_id )
 542              $classes[] = 'current_page_parent';
 543  
 544          $menu_items[$key]->classes = array_unique( $classes );
 545      }
 546      $active_ancestor_item_ids = array_filter( array_unique( $active_ancestor_item_ids ) );
 547      $active_parent_item_ids = array_filter( array_unique( $active_parent_item_ids ) );
 548      $active_parent_object_ids = array_filter( array_unique( $active_parent_object_ids ) );
 549  
 550      // set parent's class
 551      foreach ( (array) $menu_items as $key => $parent_item ) {
 552          $classes = (array) $parent_item->classes;
 553          $menu_items[$key]->current_item_ancestor = false;
 554          $menu_items[$key]->current_item_parent = false;
 555  
 556          if (
 557              isset( $parent_item->type ) &&
 558              (
 559                  // ancestral post object
 560                  (
 561                      'post_type' == $parent_item->type &&
 562                      ! empty( $queried_object->post_type ) &&
 563                      is_post_type_hierarchical( $queried_object->post_type ) &&
 564                      in_array( $parent_item->object_id, $queried_object->ancestors ) &&
 565                      $parent_item->object != $queried_object->ID
 566                  ) ||
 567  
 568                  // ancestral term
 569                  (
 570                      'taxonomy' == $parent_item->type &&
 571                      isset( $possible_taxonomy_ancestors[ $parent_item->object ] ) &&
 572                      in_array( $parent_item->object_id, $possible_taxonomy_ancestors[ $parent_item->object ] ) &&
 573                      (
 574                          ! isset( $queried_object->term_id ) ||
 575                          $parent_item->object_id != $queried_object->term_id
 576                      )
 577                  )
 578              )
 579          ) {
 580              $classes[] = empty( $queried_object->taxonomy ) ? 'current-' . $queried_object->post_type . '-ancestor' : 'current-' . $queried_object->taxonomy . '-ancestor';
 581          }
 582  
 583          if ( in_array(  intval( $parent_item->db_id ), $active_ancestor_item_ids ) ) {
 584              $classes[] = 'current-menu-ancestor';
 585              $menu_items[$key]->current_item_ancestor = true;
 586          }
 587          if ( in_array( $parent_item->db_id, $active_parent_item_ids ) ) {
 588              $classes[] = 'current-menu-parent';
 589              $menu_items[$key]->current_item_parent = true;
 590          }
 591          if ( in_array( $parent_item->object_id, $active_parent_object_ids ) )
 592              $classes[] = 'current-' . $active_object . '-parent';
 593  
 594          if ( 'post_type' == $parent_item->type && 'page' == $parent_item->object ) {
 595              // Back compat classes for pages to match wp_page_menu()
 596              if ( in_array('current-menu-parent', $classes) )
 597                  $classes[] = 'current_page_parent';
 598              if ( in_array('current-menu-ancestor', $classes) )
 599                  $classes[] = 'current_page_ancestor';
 600          }
 601  
 602          $menu_items[$key]->classes = array_unique( $classes );
 603      }
 604  }
 605  
 606  /**
 607   * Retrieve the HTML list content for nav menu items.
 608   *
 609   * @uses Walker_Nav_Menu to create HTML list content.
 610   * @since 3.0.0
 611   * @see Walker::walk() for parameters and return description.
 612   */
 613  function walk_nav_menu_tree( $items, $depth, $r ) {
 614      $walker = ( empty($r->walker) ) ? new Walker_Nav_Menu : $r->walker;
 615      $args = array( $items, $depth, $r );
 616  
 617      return call_user_func_array( array($walker, 'walk'), $args );
 618  }
 619  
 620  /**
 621   * Prevents a menu item ID from being used more than once.
 622   *
 623   * @since 3.0.1
 624   * @access private
 625   */
 626  function _nav_menu_item_id_use_once( $id, $item ) {
 627      static $_used_ids = array();
 628      if ( in_array( $item->ID, $_used_ids ) )
 629          return '';
 630      $_used_ids[] = $item->ID;
 631      return $id;
 632  }
 633  add_filter( 'nav_menu_item_id', '_nav_menu_item_id_use_once', 10, 2 );


Generated: Tue Mar 25 01:41:18 2014 WordPress honlapkészítés: online1.hu