You’re right that we need to handle parent-child relationships differently. Let me explain the approach and then show you the code changes needed.
The key is to:
- First get only top-level categories (parent = 0)
- For each top-level category, check for child categories
- Display the hierarchy properly in the accordion
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.13.2/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.13.2/jquery-ui.min.js"></script>
<?php
echo '<div class="accordion">';
// Get only top-level categories
$args = array(
'parent' => 0,
'orderby' => 'name',
'order' => 'ASC'
);
$parent_categories = get_categories($args);
foreach ($parent_categories as $parent_category) {
// Display parent category
echo '<h2>' . $parent_category->name . '</h2>';
echo '<div><p>';
// Get posts for parent category
$parent_args = array(
'post_type' => array('post','book','video'),
'posts_per_page' => -1,
'orderby' => 'date',
'order' => 'DESC',
'post_status'=> 'publish',
'cat' => $parent_category->term_id
);
$parent_posts = new WP_Query($parent_args);
while ($parent_posts->have_posts()) {
$parent_posts->the_post();
echo get_the_date();
echo ' ';
$post_type = get_post_type();
echo 'Type: ';
echo ucfirst($post_type);
echo ' ';
echo '<a target="_blank" href="';
the_permalink();
echo '">';
the_title();
echo '</a>';
echo ' ';
echo wp_trim_words(get_the_excerpt(),20,'...');
echo '<br />';
}
wp_reset_postdata();
// Get child categories
$child_args = array(
'parent' => $parent_category->term_id,
'orderby' => 'name',
'order' => 'ASC'
);
$child_categories = get_categories($child_args);
// Display child categories and their posts
foreach ($child_categories as $child_category) {
echo '<h3>' . $child_category->name . '</h3>';
echo '<div><p>';
$child_post_args = array(
'post_type' => array('post','book','video'),
'posts_per_page' => -1,
'orderby' => 'date',
'order' => 'DESC',
'post_status'=> 'publish',
'cat' => $child_category->term_id
);
$child_posts = new WP_Query($child_post_args);
while ($child_posts->have_posts()) {
$child_posts->the_post();
echo get_the_date();
echo ' ';
$post_type = get_post_type();
echo 'Type: ';
echo ucfirst($post_type);
echo ' ';
echo '<a target="_blank" href="';
the_permalink();
echo '">';
the_title();
echo '</a>';
echo ' ';
echo wp_trim_words(get_the_excerpt(),20,'...');
echo '<br />';
}
wp_reset_postdata();
echo '</p></div>';
}
echo '</p></div>';
}
echo '</div>';
?>
<script>
jQuery(document).ready(function() {
jQuery(".accordion").accordion({
collapsible: true,
clearStyle: true,
active: false,
});
});
</script>
- First, we get only top-level categories using get_categories() with ‘parent’ => 0
- For each parent category, we:
- Display the parent category name as an accordion header ()
- Show all posts belonging to that parent category
- Get all child categories of that parent
- For each child category, display it as a sub-header () with its posts