4
votes

I am setting up a template for a Wordpress Woocommerce site and I want to display a list of product categories, subcategories, and products to act as a dynamic menu. I want it to behave like this;

category 1
  -subcategory 1
    -product 1
    -product 2
  -subcategory 2
    -product 3 
category 2
  -product 4

I have found the following code that is close to 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
);
?>

<?php
$all_categories = get_categories( $args );
foreach ($all_categories as $cat) {

    if($cat->category_parent == 0) {
        $category_id = $cat->term_id;
        $thumbnail_id = get_woocommerce_term_meta( $cat->term_id, 'thumbnail_id', true );
        $image = wp_get_attachment_url( $thumbnail_id );
        echo "<ul class='category'><li>".$cat->name;
            $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 "<ul class='subcategory'>";
                        if($sub_cats->$sub_category == 0) {
                            echo "<li>".$sub_category->cat_name;
                            /*echo "<pre>";
                            print_r($sub_category);
                            echo "</pre>";*/

                            $args = array( 'post_type' => 'product','product_cat' => $sub_category->slug);
                            $loop = new WP_Query( $args );
                            echo "<ul class='products'>";
                                while ( $loop->have_posts() ) : $loop->the_post(); global $product; ?> <li>
                                    <a href="<?php echo get_permalink( $loop->post->ID ) ?>" title="<?php echo esc_attr($loop->post->post_title ? $loop->post->post_title : $loop->post->ID); ?>">
                                        <?php the_title(); ?>
                                    </a></li>
                                <?php endwhile; ?>
                            </ul>
                            <?php wp_reset_query(); ?>
                        <?php
                        } else {
                            echo "</li></ul></li>";
                        }
                        echo "</ul>";
                    }
                } else {
                    $args = array( 'post_type' => 'product', 'product_cat' => $cat->slug );
                    $loop = new WP_Query( $args );
                    echo "<ul class='products'>";
                        while ( $loop->have_posts() ) : $loop->the_post(); global $product; ?> <li>
                            <a href="<?php echo get_permalink( $loop->post->ID ) ?>" title="<?php echo esc_attr($loop->post->post_title ? $loop->post->post_title : $loop->post->ID); ?>">
                                <?php the_title(); ?>
                            </a></li>
                        <?php endwhile; ?>
                    </ul></li></ul>
                    <?php wp_reset_query();
                }
            } else {
                echo "</li></ul>";
        }
}
?>

but this does not correctly close the category which contains a subcategory, and it looks like this instead:

category 1
  -subcategory 1
    -product 1
    -product 2
  -subcategory 2
    -product 3 
  category 2
    -product 4

Notice how category 2 is aligned with the subcategories.

I would appreciate your help with this issue.

1
Not quite what I was after. Bear with me as I am a coding novice. That link appears to be for a custom page whereby I want to have something that will replace the menu for the website. The code I posted above works except for the issue with the closing tags for the category which contains a subcategory. I suspect that the check to see if the category has a parent is faulty.whalecabinet

1 Answers

4
votes

After much fussing about I changed the code to this;

<?php
$taxonomy = 'product_cat';
$orderby = 'name';
$order = 'ASC';
$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 = 1;

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

$all_categories = get_categories( $args );
foreach ($all_categories as $cat) {
    $category_id = $cat->term_id;
    $args2 = array('taxonomy' => $taxonomy,'parent' => $category_id,'hierarchical' => $hierarchical, 'orderby' => $orderby, 'order' => $order,'hide_empty' => $empty);
$categories = get_categories( $args2 );
$categories_cnt = count(get_categories( $args2 ));


if ($categories_cnt != 0){
echo "<ul class='category'><li>".$cat->name;
$sub_cats = get_categories( $args2 );
            if($sub_cats) {
echo "<ul>";
                foreach($sub_cats as $sub_category) {
                    echo "<li>".$sub_category->cat_name;

                    $args = array( 'post_type' => 'product','product_cat' => $sub_category->slug, 'orderby' => $orderby, 'order' => $order);
                            $loop = new WP_Query( $args );
                            echo "<ul class='products'>";
                                while ( $loop->have_posts() ) : $loop->the_post(); global $product; ?> <li>
                                    <a href="<?php echo get_permalink( $loop->post->ID ) ?>" title="<?php echo esc_attr($loop->post->post_title ? $loop->post->post_title : $loop->post->ID); ?>">
                                        <?php the_title(); ?>
                                    </a></li>
                                <?php endwhile; ?>
                            </ul>
                            <?php wp_reset_query(); ?>

                    <?php echo "</li>";

                    }
echo "</ul></ul>";
}
}
else {
    echo "<ul class='category'><li>".$cat->name;
    $args = array( 'post_type' => 'product', 'product_cat' => $cat->slug, 'orderby' => $orderby, 'order' => $order );
                    $loop = new WP_Query( $args );
                    echo "<ul class='products'>";
                        while ( $loop->have_posts() ) : $loop->the_post(); global $product; ?> <li>
                            <a href="<?php echo get_permalink( $loop->post->ID ) ?>" title="<?php echo esc_attr($loop->post->post_title ? $loop->post->post_title : $loop->post->ID); ?>">
                                <?php the_title(); ?>
                            </a></li>
                        <?php endwhile; ?>
                    </ul></li></ul>
                    <?php wp_reset_query();
    echo "</li></ul>";

}

}
?>

I am sure that it is quite messy and probably contains redundant code but it is working for me now.