1

I have main menu which displays two types of links: CPT and Subcategory. I create the menu with a custom request: I retrieve the Custom Post Type then the sub-categories of the main category in Alphabetical order :

Category A: - Product a - Product b - sub category a - sub category b ...

But, my client wants a custom display example:

Category A: sub category a - Product b - Product a - sub category b ...

I thought about creating a Drag Drop solution ... but how to implement it

2 Answers 2

1

You can use this plugin for sorting custom post type or taxonomy

1
  • Yes but i must mix CPT and Sub Categories , i have two WP Query
    – Younes.D
    Nov 26, 2020 at 23:25
1

you can get the product categories using the get_terms() and a loop.

<?php
$cat_args = array( 'orderby' => 'name', 'order' => 'asc', 'hide_empty' => true);
$cats = get_terms( 'product_cat', $cat_args );
foreach ($cats as $key => $cat):
  if ($cat->parent == 0): ?>
    <a href="<?php echo get_term_link($cat) ?>"><?php echo $cat->name; ?></a> <?php
  endif;
endforeach;

This gives back the categories ("first generation"), to have sub-categories we just need to add a new loop inside the one we have. next code goes already until the third generation.

<?php
$cat_args = array( 'orderby' => 'name', 'order' => 'asc', 'hide_empty' => true);
$cats = get_terms( 'product_cat', $cat_args );
foreach ($cats as $key => $cat):
  if ($cat->parent == 0): ?>
    <a href="<?php echo get_term_link($cat) ?>"><?php echo $cat->name; ?></a> <?php
    foreach ($cats as $key => $cat2):
      if ($cat2->parent == $cat->term_id): ?>
        <a href="<?php echo get_term_link($cat2) ?>"><?php echo $cat2->name; ?></a> <?php
        foreach ($cats as $key => $cat3):
          if ($cat3->parent == $cat2->term_id): ?>
            <a href="<?php echo get_term_link($cat3) ?>"><?php echo $cat3->name; ?></a><?php
          endif;
        endforeach;
      endif;
    endforeach; 
  endif;
endforeach;

This only shows the categories with products, to have all the categories just change the 'hide_empty' on the first line to false.

To show the products name of a category or sub-category we can use this function.

<?php
function get_prod($prod_per_page, $prod_slug){
  $args = array( 'posts_per_page' => $prod_per_page,
                 'tax_query' => array(
                 'relation' => 'AND',
                  array('taxonomy' => 'product_cat',
                        'field' => 'slug',
                        'terms' => $prod_slug
                      )
                  ),
                  'post_type' => 'product',
                  'orderby' => 'title'
          );
  $products = new WP_Query( $args );
  echo "<ul>";
  while ( $products->have_posts() ) {
      $products->the_post(); ?>
          <li>
              <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
          </li> <?php
  }
  wp_reset_postdata(); 
  echo "</ul>";
}

Now we can add next to the a tag this custom function that has 2 parameters, first the number of products to show, where -1 is all and e.g. for 4 products is 4, the second is the category slug.

And here it is the answer, now you can delete the 3th "generation" of categories if not needed and change the number of products to show per page.

<?php
function get_prod($prod_per_page, $prod_slug){
  $args = array( 'posts_per_page' => $prod_per_page,
                 'tax_query' => array(
                 'relation' => 'AND',
                  array('taxonomy' => 'product_cat',
                        'field' => 'slug',
                        'terms' => $prod_slug
                      )
                  ),
                  'post_type' => 'product',
                  'orderby' => 'title'
          );
  $products = new WP_Query( $args );
  echo "<ul>";
  while ( $products->have_posts() ) {
      $products->the_post(); ?>
          <li>
              <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
          </li> <?php
  }
  wp_reset_postdata(); 
  echo "</ul>";
}
$cat_args = array( 'orderby' => 'name', 'order' => 'asc', 'hide_empty' => true);
$cats = get_terms( 'product_cat', $cat_args );
foreach ($cats as $key => $cat):
  if ($cat->parent == 0): ?>
    <a href="<?php echo get_term_link($cat) ?>"><?php echo $cat->name; ?></a> <?php
    get_prod(-1, $cat->slug);
    foreach ($cats as $key => $cat2):
      if ($cat2->parent == $cat->term_id): ?>
        <a href="<?php echo get_term_link($cat2) ?>"><?php echo $cat2->name; ?></a> <?php
        get_prod(10, $cat2->slug);
        foreach ($cats as $key => $cat3):
          if ($cat3->parent == $cat2->term_id): ?>
            <a href="<?php echo get_term_link($cat3) ?>"><?php echo $cat3->name; ?></a><?php
            get_prod(4, $cat3->slug);
          endif;
        endforeach;
      endif;
    endforeach;
  endif;
endforeach;

The first parameter of this get_prod() is to change for the number of products each one wants to show.

the html, css or javascript can be added! Hope that it helps!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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