最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

categories - get_posts() from parent category only using a shortcode

programmeradmin1浏览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.

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.

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:

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.

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.

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:

Share Improve this question edited Jul 13, 2019 at 14:20 Tes3awy asked Jul 12, 2019 at 22:54 Tes3awyTes3awy 1058 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 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,.

发布评论

评论列表(0)

  1. 暂无评论