3

I want to get all woocommerce category's in front-end with subcategory like this result:

<ul>
    <li><a href="">Link</a>
        <ul>
            <li><a href="">Submenu link</a></li>
        </ul>
    </li>
</ul>

Here is what i have (But it's Not what i want) :

<?php

  $taxonomy     = 'product_cat';
  $orderby      = 'name';  
  $show_count   = 0;      // 1 for yes, 0 for no
  $pad_counts   = 0;      // 1 for yes, 0 for no
  $hierarchical = 1;      // 1 for yes, 0 for no  
  $title        = '';  
  $empty        = 0;

  $args = array(
         'taxonomy'     => $taxonomy,
         'orderby'      => $orderby,
         'show_count'   => $show_count,
         'pad_counts'   => $pad_counts,
         'hierarchical' => $hierarchical,
         'title_li'     => $title,
         'hide_empty'   => $empty
  );
 $all_categories = get_categories( $args );
 foreach ($all_categories as $cat) {
    if($cat->category_parent == 0) {
        $category_id = $cat->term_id;       
        echo '<li><a href="'. get_term_link($cat->slug, 'product_cat') .'">'. $cat->name .'</a></li>';

        $args2 = array(
                'taxonomy'     => $taxonomy,
                'child_of'     => 0,
                'parent'       => $category_id,
                'orderby'      => $orderby,
                'show_count'   => $show_count,
                'pad_counts'   => $pad_counts,
                'hierarchical' => $hierarchical,
                'title_li'     => $title,
                'hide_empty'   => $empty
        );
        $sub_cats = get_categories( $args2 );
            if($sub_cats) {
                foreach($sub_cats as $sub_category) {
                    echo  '<li><a href="'. get_term_link($sub_category->slug, 'product_cat') .'">'. $sub_category->name .'</a></li>';
                }
            }
        }       
}
?>  

this code show's category and subcategory but the subcategory is not where should be, the subcategory is like separate link like this:

<ul>
    <li><a href="">link</a></li>
    <li><a href="">Submenu link</a></li>
</ul>
Ali Babae
  • 150
  • 1
  • 2
  • 11

6 Answers6

13

You could try this code:

  $args = array(
          'taxonomy' => 'product_cat',
          'hide_empty' => false,
          'parent'   => 0
      );
  $product_cat = get_terms( $args );

  foreach ($product_cat as $parent_product_cat)
  {

  echo '
      <ul>
        <li><a href="'.get_term_link($parent_product_cat->term_id).'">'.$parent_product_cat->name.'</a>
        <ul>
          ';
  $child_args = array(
              'taxonomy' => 'product_cat',
              'hide_empty' => false,
              'parent'   => $parent_product_cat->term_id
          );
  $child_product_cats = get_terms( $child_args );
  foreach ($child_product_cats as $child_product_cat)
  {
    echo '<li><a href="'.get_term_link($child_product_cat->term_id).'">'.$child_product_cat->name.'</a></li>';
  }

  echo '</ul>
      </li>
    </ul>';
  }

This will Print in your WooCommerce, Wordpress based site.

Peyman Naeimi
  • 390
  • 3
  • 15
4
$taxonomy     = 'product_cat';
$orderby      = 'name';  
$show_count   = 0;      
$pad_counts   = 0;      
$hierarchical = 1;      
$title        = '';  
$empty        = 0;

$args = array(
    'taxonomy'     => $taxonomy,
    'orderby'      => $orderby,
    'show_count'   => $show_count,
    'pad_counts'   => $pad_counts,
    'hierarchical' => $hierarchical,
    'title_li'     => $title,
    'hide_empty'   => $empty
);

$all_categories = get_categories( $args );

foreach ($all_categories as $cat) {

    if($cat->category_parent == 0) {

        $category_id = $cat->term_id;

        echo '<br /> ('. $category_id .') <a href="'. get_term_link($cat->slug, 'product_cat') .'">'. $cat->name .'</a>';

        $args2 = array(
            'taxonomy'     => $taxonomy,
            'parent'       => $category_id,
            'orderby'      => $orderby,
            'show_count'   => $show_count,
            'pad_counts'   => $pad_counts,
            'hierarchical' => $hierarchical,
            'title_li'     => $title,
            'hide_empty'   => $empty
        );

        $sub_cats = get_categories( $args2 );

        if($sub_cats) {

            foreach($sub_cats as $sub_category) {
                echo  '<br/> > <a href="'. get_term_link($sub_category->slug, 'product_cat') .'">'. $sub_category->name .'</a>';
                echo apply_filters( 'woocommerce_subcategory_count_html', ' (' . $sub_category->count . ')', $category );


                 $args3 = array(
            'taxonomy'     => $taxonomy,
            'parent'       =>  $sub_category->term_id,
            'orderby'      => $orderby,
            'show_count'   => $show_count,
            'pad_counts'   => $pad_counts,
            'hierarchical' => $hierarchical,
            'title_li'     => $title,
            'hide_empty'   => $empty
        );

        $sub_cats3 = get_categories( $args3 );

        if($sub_cats3) {

            foreach($sub_cats3 as $sub_category3) {
                echo  '<br/> > > <a href="'. get_term_link($sub_category3->slug, 'product_cat') .'">'. $sub_category3->name .'</a>';
                echo apply_filters( 'woocommerce_subcategory_count_html', ' (' . $sub_category3->count . ')', $category );

            }


                 }

            }
        }
    }       
}
Manzurul
  • 130
  • 1
  • 1
  • 8
3

get_categories() uses get_terms() which uses WP_Term_Query().

So you can check WP_Term_Query::__construct() for information on accepted arguments.

Try this:

$args = array(
    'taxonomy' => 'product_cat',
    'get' => 'all'
);
$categories = get_categories($args);
Mario Shtika
  • 1,436
  • 19
  • 31
1
<?php

  $taxonomy     = 'product_cat';
  $orderby      = 'name';  
  $show_count   = 0;      // 1 for yes, 0 for no
  $pad_counts   = 0;      // 1 for yes, 0 for no
  $hierarchical = 1;      // 1 for yes, 0 for no  
  $title        = '';  
  $empty        = 0;

  $args = array(
         'taxonomy'     => $taxonomy,
         'orderby'      => $orderby,
         'show_count'   => $show_count,
         'pad_counts'   => $pad_counts,
         'hierarchical' => $hierarchical,
         'title_li'     => $title,
         'hide_empty'   => $empty
  );
 $all_categories = get_categories( $args );
 foreach ($all_categories as $cat) {
    if($cat->category_parent == 0) {
        $category_id = $cat->term_id;       
        echo '<br /><a href="'. get_term_link($cat->slug, 'product_cat') .'">'. $cat->name .'</a>';

        $args2 = array(
                'taxonomy'     => $taxonomy,
                'child_of'     => 0,
                'parent'       => $category_id,
                'orderby'      => $orderby,
                'show_count'   => $show_count,
                'pad_counts'   => $pad_counts,
                'hierarchical' => $hierarchical,
                'title_li'     => $title,
                'hide_empty'   => $empty
        );
        $sub_cats = get_categories( $args2 );
        if($sub_cats) {
            foreach($sub_cats as $sub_category) {
                echo  $sub_category->name ;
            }   
        }
    }       
}
?>
KTrivedi
  • 131
  • 1
  • 5
  • Hello Benjamin I have made Two Query one for extracting categories and one for extracting subcategories and also used custom taxonomy so that categories of post will not get mixed with the categories of woocommerce products We have made 2nd Query to fetch subcategory according to the parent category and using foreach we can display categories and subcategories where we want to display – KTrivedi Jun 20 '17 at 06:37
  • I meant, in the body of your question :) You can use the edit link for this. That will help the the OP understand it! – BenMorel Jun 20 '17 at 07:16
  • hehe yes but i have made custom query for that and i learn from wordpress codex only Thanks for the suggestion :) – KTrivedi Jun 20 '17 at 07:38
1

Based on Peyman's answer, if you have subcategories within other subcategories, you can use a recursive function:

function get_wc_categories(int $parent = 0): string {

    $text = '<ul>';

    $args = array(
        'taxonomy' => 'product_cat',
        'hide_empty' => false,
        'parent'   => $parent
    );

    $product_cat = get_terms($args);

    if (empty($product_cat)) {
        return '';
    }

    foreach ($product_cat as $parent_product_cat) {

        $text .= '<li><a href="'.get_term_link($parent_product_cat->term_id).'">'.$parent_product_cat->name.'</a>';

        $text .= get_wc_categories($parent_product_cat->term_id);

        $text .= '</li>';
    }
    return $text . '</ul>';
}

So where you want to show the categories, use somtehing like this:

echo get_wc_categories();

0

to get all the categories and maintain the hierarchy you have to use a recursive function. consider you have the following woocommerce categories hierarchy: (category name, parent)

Clothing 0

---Accessories 127

------Perfume 130

---------paris 141

---Hoodies 127

---Tshirts 127

Decor 0

Music 0

Uncategorized 0

write a function to get the parent categories only:

function getparentcategories()
    {
        $taxonomy     = 'product_cat';
        $orderby      = 'name';
        $show_count   = 0;      
        $pad_counts   = 0;      
        $hierarchical = 1;      
        $title        = '';
        $empty        = 0;

        $args = array(
            'taxonomy'     => $taxonomy,
            'orderby'      => $orderby,
            'show_count'   => $show_count,
            'pad_counts'   => $pad_counts,
            'hierarchical' => $hierarchical,
            'title_li'     => $title,
            'hide_empty'   => $empty
        );

        $all_categories = get_categories( $args );
        return $all_categories;
    }

then write a second recursive function to get subcategory of each parent and pass by reference a two dimensional array to hold the category and its level:

function getcatsubs($items,&$arg,$level=0)
    {
        $taxonomy     = 'product_cat';
        $orderby      = 'name';
        $show_count   = 0;
        $pad_counts   = 0;
        $hierarchical = 1;
        $title        = '';
        $empty        = 0;

        if($items) {
            $category_id = $items->term_id;
            $args = array(
                'taxonomy' => $taxonomy,
                'child_of' => 0,
                'parent' => $category_id,
                'orderby' => $orderby,
                'show_count' => $show_count,
                'pad_counts' => $pad_counts,
                'hierarchical' => $hierarchical,
                'title_li' => $title,
                'hide_empty' => $empty
            );
            $sub_cats = get_categories($args);
            if($sub_cats)
            {
                foreach ($sub_cats as $sub)
                {
                    $category_id = $sub->term_id;
                    $args2 = array(
                        'taxonomy' => $taxonomy,
                        'child_of' => 0,
                        'parent' => $category_id,
                        'orderby' => $orderby,
                        'show_count' => $show_count,
                        'pad_counts' => $pad_counts,
                        'hierarchical' => $hierarchical,
                        'title_li' => $title,
                        'hide_empty' => $empty
                    );
                    array_push($arg[0],$sub);
                    array_push($arg[1],$level);
                    static::getcatsubs($sub,$arg,$level+1);
                }
            }
            else
            {
                return;
            }
        }
        else
        {
            return;
        }
    }

execute the following code to get the hierarchy of categories as printed above:

$cats=getparentcategories();
foreach ($cats as $cat)
{
    if($cat->parent==0) {
        echo "<p>$cat->name $cat->parent</p>";
        $arg=[[],[]];
        getcatsubs($cat,$arg);
        if ($arg[0]) {
            $l=0;
            foreach ($arg[0] as $scat) {
                $i=$arg[1][$l];
                echo "<p>---";
                for ($x=0;$x<$i;$x++)
                    echo "---";
                echo "$scat->name $scat->parent</p>";
                $l++;
            }
        }
    }
}