WordPress.org

Make WordPress Core

Opened 4 years ago

Closed 8 months ago

Last modified 8 months ago

#14698 closed enhancement (wontfix)

Adding custom menu items in a WP managed menu

Reported by: mackeyn@… Owned by:
Milestone: Priority: normal
Severity: minor Version: 3.0.1
Component: Menus Keywords:
Focuses: Cc:

Description

In Walker:walk() line 932 of classes.php (WP version 3.0.1), the comparison of the parent ID to 0 is done so using ==. This is an issue if you're trying to manually insert a menu item for a term within a menu consisting of posts. I would like to be able to set the parent_id to something like 'term:4' (with 4 being the ID of the term). But because it is a string and comparing a string to zero with == will always equate to false.

I suggest that line 932 is changed from:

if ( 0 == $e->$parent_field )

to:

if ( empty( $e->$parent_field ) )

The end result I'm looking for is a way to take an existing menu and add in sub-items for a particular item that contains all the terms from a given taxonomy. Then for each of the term items, add child items for all of the custom posts associated to the term. For the time being, I'm using a negative db_id to bypass the comparison issue.

Here's a sample of my code:

function my_get_nav_menu_items($items, $menu, $args) {
  if ($menu->slug != 'primary') {
    return $items;
  }
  $findAProgram = null;
  foreach ($items as $item) {
    if ($item->post_name = 'find-a-program') {
      $findAProgram = $item;
      break;
    }
  }
  if ($findAProgram) {
    $order = count($items);
    foreach (get_terms('program-focus') as $term) {
      $posts = get_posts("taxonomy=program-focus&term={$term->term_slug}&post_type=programs");
      if (!empty($posts)) {
        $term = wp_setup_nav_menu_item($term);
        $term->menu_item_parent = $findAProgram->db_id;
        // set db_id to negitive value to avoid collisions with posts with the same ID
        // This is needed due to the non-strict equality check in classes.php
        // line 932 in Walker::walk().  I would love to use a string for the
        // term ID's (something like 'term:4'), but "any string" == 0 will
        // always return false.
        $term->db_id = -1*$term->ID;
        $term->menu_order = $order++;
        $items[] = $term;
        foreach ($posts as $post) {
          $post = wp_setup_nav_menu_item($post);
          $post->menu_item_parent = $term->db_id;
          $post->menu_order = $order++;
          $items[] = $post;
        }
      }
    }
  }
  return $items;
}
add_filter('wp_get_nav_menu_items', 'my_get_nav_menu_items', 10, 3);

Change History (8)

comment:1 mackeyn@…4 years ago

  • Summary changed from Added custom menu items to Adding custom menu items in a WP managed menu

comment:2 nacin3 years ago

  • Milestone Awaiting Review deleted
  • Resolution set to invalid
  • Status changed from new to closed

This looks like a dirty, dirty hack, and a change to empty() should not be done to support it.

comment:3 mackeyn@…3 years ago

  • Resolution invalid deleted
  • Status changed from closed to reopened

I agree that the following lines of code is a pretty nasty hack

// set db_id to negitive value to avoid collisions with posts with the same ID
        // This is needed due to the non-strict equality check in classes.php
        // line 932 in Walker::walk().  I would love to use a string for the
        // term ID's (something like 'term:4'), but "any string" == 0 will
        // always return false.
        $term->db_id = -1*$term->ID;

That doesn't change the fact that it's not possible to inject a mixture of posts and categorizes into a menu without the risk of a collision in db_id's. It doesn't really matter to me how this is fixed. In fact the requirements on my project changed and we ended up using a custom post type instead of a category. In my opinion, wp_setup_nav_menu_item() should be able to prepare pages, posts, categories, menu_items, etc. to be added to a menu. The way that it is now, if a page and a taxonomy term have the same db_id, the one will override the other. If you really feel strongly that this doesn't warrant a fix, please re-close it and I'll leave it alone. Just trying to help.

comment:4 hakre3 years ago

  • Keywords needs-patch added

comment:5 wahyuariest3 years ago

set db_id to negitive value to avoid collisions with posts with the same ID

This is needed due to the non-strict equality check in classes.php
line 932 in Walker::walk(). I would love to use a string for the
term ID's (something like 'term:4'), but "any string" == 0 will
always return false.
$term->db_id = -1*$term->ID;

comment:6 ocean903 years ago

  • Milestone set to Awaiting Review

comment:7 c3mdigital8 months ago

  • Keywords needs-patch removed
  • Resolution set to invalid
  • Status changed from reopened to closed

Doesn't seem like there is a viable solution and not clear if there is actually a problem. Please re open if you feel otherwise.

comment:8 SergeyBiryukov8 months ago

  • Milestone Awaiting Review deleted
  • Resolution changed from invalid to wontfix
Note: See TracTickets for help on using tickets.