These seems like it won’t perform well (you’ll probably want to add it some caching), but it works:
// Get all the terms for taxonomy.
$terms = get_terms( array(
'taxonomy' => 'wpse416749',
) );
echo '<ul>';
foreach ( $terms as $term ) {
// Get pages with the current term.
$knowledges = new WP_Query( array(
'post_type' => 'knowledges',
'posts_per_page' => -1,
'no_found_rows' => true,
'fields' => 'ids',
'tax_query' => array(
array(
'taxonomy' => 'wpse416749',
'terms' => $term->term_id,
),
),
) );
// Get the ancestors for each page with current term.
// Add ancestor IDs to array of page IDs.
foreach ( $knowledges->posts as $post ) {
$ancestors = get_ancestors( $post, 'knowledges', 'post_type' );
if ( empty( $ancestors ) ) {
continue;
}
$knowledges->posts = array_merge( $knowledges->posts, $ancestors );
}
// Ensure no duplicate IDs.
$knowledges->posts = array_unique( $knowledges->posts );
// Print the term's name.
printf( '<li>%s<ul>', esc_html( $term->name ) );
// List the pages in current term with ancestors.
wp_list_pages( array(
'post_type' => 'knowledges',
'include' => $knowledges->posts,
'title_li' => null,
) );
echo '</ul></li>';
}
echo '</ul>';