I asked ChatGPT to clean up this code and it did a pretty good job. You’ll still need to integrate your JavaScript, but this is a good start on optimization.
<?php
// Get the current post type from the request.
$current_post_type = str_replace( '-', '_', basename( $wp->request ) );
// Set up the initial query arguments to get all published posts of the determined post type.
$args = array(
'post_type' => $current_post_type,
'post_status' => 'publish',
'posts_per_page' => -1, // Get all posts.
);
// Execute the query.
$the_query = new WP_Query( $args );
// Initialize an array to keep track of categories that have posts.
$categories_with_posts = array();
if ( $the_query->have_posts() ) {
while ( $the_query->have_posts() ) {
$the_query->the_post();
// Get the categories associated with the current post.
$terms = get_the_terms( get_the_ID(), 'category' );
if ( $terms && ! is_wp_error( $terms ) ) {
foreach ( $terms as $term ) {
// Check if the term ID is not already in the array to avoid duplicates.
if ( ! array_key_exists( $term->term_id, $categories_with_posts ) ) {
// Store the term object, indexed by term ID for easy lookup.
$categories_with_posts[ $term->term_id ] = $term;
}
}
}
}
wp_reset_postdata();
}
// Display the categories if there are any with posts.
if ( ! empty( $categories_with_posts ) ) {
echo '<ul class="filter-list">';
// Iterate over the categories with posts.
foreach ( $categories_with_posts as $term_id => $category ) {
// Determine if the category is a parent or child by checking its parent property.
$class = 0 === $category->parent ? 'parent' : 'child';
// Query to get the post count for the current category and post type.
$post_count_args = array(
'post_type' => $current_post_type,
'category' => $category->term_id,
'posts_per_page' => -1, // Get all posts.
);
$post_count_query = new WP_Query( $post_count_args );
$post_count = $post_count_query->found_posts;
// Only display categories that are not named "all-articles" and have posts.
if ( 'all-articles' !== $category->slug && $post_count > 0 ) {
echo sprintf(
'<li class="%s"><a class="%s" @click="filterPosts(%d)">%s (%d)</a></li>',
esc_attr( $class ),
esc_attr( $class ),
esc_attr( $category->term_id ),
esc_html( $category->name ),
$post_count
);
}
}
echo '</ul>';
}
The code is well-commented, so it should be clear what’s going on. More broadly, instead of doing separate queries for parent and child categories, it gets all of them in one query and stores them in an associative array for easier usage.
The logic around display is consolidated into one section and the output is handled methodically with sprintf for easy maintenance.