At the top of a product archive page I am trying to display a list of product categories. The rule should be that the list always shows the direct children of the top level.

There are several answers on WPA which I have been trying to implement (with my minimal skills) but I am missing something.

Here's the query:

    $taxonomy     = 'product_cat';
    $orderby      = 'name';
    $order        = 'DESC';
    $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;

   // So now I need to get the top parent id in a variable. I tried these 4 options

     // option 1
     $queried_object = get_queried_object();
    $term_id = $queried_object->term_id;

    // option 2
    $thisCat = get_category( get_query_var( 'cat' ) ); 
    while ( intval($thisCat->parent) > 0 ) {
      $thisCat = get_category ( $thisCat->parent );
     $term_id = $thisCat->term_id

    //option 3
    $parent  = get_term_by( 'id', $term_id, $taxonomy);
    while ($parent->parent != 0){
        $parent  = get_term_by( 'id', $parent->parent, $taxonomy);

    //option 4
    while ($catid) {
      $cat = get_category($catid); // get the object for the catid
      $catid = $cat->category_parent; // assign parent ID (if exists) to $catid
      // the while loop will continue whilst there is a $catid
      // when there is no longer a parent $catid will be NULL so we can assign our $catParent
      $catParent = $cat->cat_ID;

            // Testing if I have the correct value
    echo 'The returned variable is:'; print_r($term_id);

    $args2 = array(
      'taxonomy'     => $taxonomy,
      'child_of'     => $term_id,
      'orderby'      => $orderby,
      'order'        => $order,
      'show_count'   => $show_count,
      'pad_counts'   => $pad_counts,
      'hierarchical' => $hierarchical,
      'title_li'     => $title,
      'hide_empty'   => $empty

    $sub_cats = get_categories( $args2 );

    $args = array(
        //'type'          => 'post',
        'orderby'       => 'term_group',
        'hide_empty'    => 0,
        'hierarchical'  => 0,
        'parent'        => 0,
        'taxonomy'      => 'product_cat'
    $test = get_categories( $args ); 

    $cat_id = get_query_var('cat');
    echo $cat_id;

    if (!empty($sub_cats)) { 

    echo '<ul class="categories">'; 

    foreach($sub_cats as $sub_category) {

        //echo 'de variabele sub_category'; print_r($sub_category);

        if ($sub_cats->$sub_category == 0) {
            $thumbnail_id  = get_woocommerce_term_meta( $sub_category->term_id, 'thumbnail_id', true );
            $image = wp_get_attachment_url( $thumbnail_id );
            $name = $sub_category->name;
            $slug = $sub_category->slug;

            echo '<li class="cat-item '.$slug.'"><a href="'. get_term_link($sub_category->slug, 'product_cat') .'"><img src="'.$image.'" " /><span class="txt">'.$name.'</span></a></li>';

        echo '<li class="cat-item search">';
        echo '</li>';

    echo '</ul>';

     } //endif !empty ?>

Thanks! Juri

  • 1
    Can you define what you mean by 'the top level'? – Tom J Nowell Jun 24 '14 at 13:21

In general to get the posts of your custom post type you need to query post_type, if you want only the categories you could just pull the categories instead of the entire post type.

<?php query_posts(array( 'post_type' => 'CustomPostType' )); ?>
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>

 <?php the_category(', '); ?>

<?php endwhile; else: ?>
<p>Sorry, no matches found.</p>
<?php endif; ?>

Or you could use get_terms()?
Quick example:

$terms = get_terms('CustomPostType');
foreach ( $terms as $term ) {
   echo $term->name.'<br />';

Are you listing anything else on that archive page? If you are for example listing posts (or other information) from the same post type you could combine it.

EDIT: I apologize I read over the comments in the script and thought you solely needed help with the rest. To just get the term id you could use get_terms() (as referred above). And then take a look at the following parameters:

 orderby (string)
    name - Default

 order (string)
    ASC - Default

number (integer) 
    The maximum number of terms to return. Default is to return them all. 

fields (string)
    all - returns an array of term objects - Default
    ids - returns an array of integers
    names - returns an array of strings
    count - (3.2+) returns the number of terms found
    id=>parent - returns an associative array where the key is the term id and the value is the parent term id if present or 0 

Not including any other parameters it would look something like this:

$CustomPostType_ids = get_terms( 'CustomPostType', array(
    'orderby'    => 'id',
    'order'      => 'ASC',
    'number'     => 1,
    'fields'     => 'ids'
) );

You could also return all values and then just pull term_id.

  • Hi MeRuud, Thanks for your reply. This custom taxonomy (Products) is generated by Woocommerce. I know to get the list of subcategories, most of the code is ok. The only thing I need is a way to get the id of the top level category as I was trying in options 1 to 4 in the code example. Thanks – Juri Apr 21 '13 at 15:15
  • To make it easier. All I need is a variable with the id of the top level product taxonomy. Seems easy but I can't manage to get it. Thanks! – Juri Apr 22 '13 at 19:28
  • I updated the answer. Hope that helps. – MeRuud Apr 23 '13 at 14:04
  • Let me know if that worked out for you. If it did please mark the answer as accepted (press the check mark next the answer). Thank you – MeRuud Apr 24 '13 at 16:11
  • Hi MeRuud, It didn't work directly because it returned an array which I couln't stip to the single value. But it was definetely the way to go. With you code I managed to construct the final solution. Thanks! This was the final code ` $queried_object = get_queried_object(); $thisTerm = get_term($queried_object, 'product_cat'); while ( intval($thisTerm->parent) > 0 ) { $thisTerm = get_category ( $thisTerm->parent ); } $term_id = $thisTerm->term_id; ` – Juri Apr 25 '13 at 14:04

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.