0

I am trying to get_posts() from a category that has a subcategory within. To show an example please look at the image just below.

Categories

So, as you can see. The parent and the children have posts inside. I want to preview the content within the children only once not twice. The following image shows what I mean. You can see that some items are retrieved twice.

Duplicates

I have created a shortcode, but I don't know how to make the first part of it get only the posts in the parent category (from desserts first), then show the posts in the subcategories (Baked cookie dough and Pancakes) if exist.

add_shortcode('TEDS_MENU', 'fetch_teds_menu_items');
function fetch_teds_menu_items($atts)
{
  $atts = shortcode_atts(array(
    'category_name' => ''
  ), $atts);

  $category = get_term_by('name', $atts['category_name'], 'category');

  if (!$category) {
    return '';
  }

  $args = array(
    'category__in' => [$category->term_id],
    'post_type' => 'menu',
    'numberposts' => -1,
    'post_status' => 'publish'
  );

  $subcategories = get_categories(
    array(
      'parent' => $category->term_id
    )
  );

  $output = '<section id="' . $category->slug . '">';
  $menu_items = get_posts($args);
  foreach ($menu_items as $menu_item) {
    setup_postdata($menu_item);
    $output .= '<div class="teds-menu-item-wrapper">';
    $output .= '<h3 class="teds-menu-item__title">' . $menu_item->post_title . '</h3>';
    $output .= '<div class="teds-menu-item">';
    $output .= '<div class="teds-menu-item-description">';
    $output .= '<p class="teds-menu-item-description__text">' . $menu_item->post_content . '</p>';
    $output .= '</div>';
    $output .= '<ul class="teds-menu-prices-list">';
    if (get_post_meta($menu_item->ID, 'regular_size_price')[0] || get_post_meta($menu_item->ID, 'large_size_price')[0]) {
      $output .= '<li class="menu-prices-list--item">R ' . get_post_meta($menu_item->ID, 'regular_size_price')[0]  . ' EGP</li>';
      $output .= '<li class="menu-prices-list--item">L ' . get_post_meta($menu_item->ID, 'large_size_price')[0] . ' EGP</li>';
    }
    if (get_post_meta($menu_item->ID, 'price')[0]) {
      $output .= '<li class="teds-menu-prices-list--item">' . get_post_meta($menu_item->ID, 'price')[0] . ' EGP</li>';
    }
    $output .= '</ul>';
    $output .= '</div>';
    $output .= '</div>';
  }
  if ($subcategories) {
    $output .= '<section class="teds-menu-subcategory">';
    foreach ($subcategories as $subcategory) {
      $output .= '<div class="teds-menu-subcategory__content">';
      $output .= '<h2 class="teds-subcategory-title">' . $subcategory->name . '</h2>';
      $subcategory_items = get_posts(array(
        'category' => $subcategory->cat_ID,
        'post_type' => 'menu',
        'numberposts' => -1,
        'post_status' => 'publish'
      ));
      foreach ($subcategory_items as $subcategory_item) {
        $output .= '<div class="teds-subcategory-item">';
        $output .= '<div class="teds-subcategory-item__content">';
        $output .= '<h3 class="teds-subcategory-item__title">' . $subcategory_item->post_title . '</h3>';
        if ($subcategory_item->post_content) {
          $output .= '<p class="class="menu-prices-list--item teds-subcategory-item__desc">' . $subcategory_item->post_content . '</p>';
        }
        $output .= '</div>';
        if (get_post_meta($subcategory_item->ID, 'price')[0]) {
          $output .= '<ul class="teds-menu-prices-list">';
          $output .= '<li class="teds-menu-prices-list--item">' . get_post_meta($subcategory_item->ID, 'price')[0] . ' EGP</li>';
          $output .= '</ul>';
        }
        $output .= '</div>';
      }
      $output .= '</div>';
      wp_reset_postdata();
    }
    wp_reset_postdata();
    $output .= '</section>';
  }
  $output .= "</section>";
  wp_reset_postdata();
  return $output;
}

UPDATE: Following @Sally CJ's answer solves the issue of some posts being displayed twice. But in some other categories, posts have disappeared. For example, the following categories include posts but they are not displayed any more:

Missing posts

Missing posts 2

Missing preview

1

If you don't want to include posts in child categories, use the category__in parameter:

$args = array(
  'category__in' => [ get_cat_ID( $category_name ) ], // use category__in
  //'category_name' => $category_name,                // and not this.
  'post_type' => 'menu',
  'numberposts' => -1,
  'post_status' => 'publish'
);

And although the above would give you what you wanted, the following might help you..

function fetch_teds_menu_items($atts)
{
  $atts = shortcode_atts(array(
    'category_name' => ''
  ), $atts);

  if ( ! $category = get_term_by( 'name', $atts['category_name'], 'category' ) ) {
    return '';
  }

  $args = array(
    'category__in' => [ $category->term_id ],
    'post_type' => 'menu',
    'numberposts' => -1,
    'post_status' => 'publish'
  );

  $meta_data = get_term_meta($category->term_id, 'category_featured_image', TRUE);
  // $category_image = wp_get_attachment_url($meta_data);

  $subcategories = get_categories(
    array(
      'parent' => $category->term_id
    )
  );

  $output = '<section id="' . $category->slug . '">';
  ...
  return $output;
}

I.e. I use get_term_by() to get the full category object by its name (not slug, but can be slug).

PS: The category parameter also include child categories — 'category' => $subcategory->cat_ID,.

  • Thanks a lot for your help. I want to ask about something because there is something weird happened. Some categories that include posts are now not displayed for some reason which I don't know why. I updated the question so you can understand me better. – Tes3awy Jul 13 at 9:33
  • Can I see your current code? And if possible, can you export published posts in the "Gourmet Burgers" & "Additions" categories? (Replace sensitive data like domain names) – Sally CJ Jul 13 at 14:10
  • I replaced the old code now. And you can find the export in gist: gist.github.com/Tes3awy/0f653de53b05eb8e5a774d850806a4d6 – Tes3awy Jul 13 at 14:21
  • Thank you, but I'm not getting the issue.. are you sure you used the correct category name (I know you might did based on the screenshot in the question, but just in case)? [TEDS_MENU category_name="Gourmet Burgers"] ? – Sally CJ Jul 13 at 15:09
  • 1
    Maybe caching issue or you forgot or made a mistake in certain parts of the code.. but whatever it was, I hope it won't happen again. :) – Sally CJ Jul 13 at 15:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.